From 6e03e5a71d849563848bc8fd4fbc65f432180dd2 Mon Sep 17 00:00:00 2001 From: xin liang Date: Thu, 29 Aug 2024 09:55:06 +0800 Subject: [PATCH 1/5] Fix: Add a new option 'fa_advised_op_values' (bsc#1228858) This option is used to automatically add the advised operation values for fencing agents. Default value is 'no', which means doesn't add the advised operation values for fencing agents. --- crmsh/cibconfig.py | 11 ++++++++++- crmsh/config.py | 1 + crmsh/parse.py | 12 ++++++++---- etc/crm.conf.in | 3 +++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/crmsh/cibconfig.py b/crmsh/cibconfig.py index a2bcb6031..24ae78855 100644 --- a/crmsh/cibconfig.py +++ b/crmsh/cibconfig.py @@ -857,6 +857,8 @@ def parse_cli_to_xml(cli, oldnode=None): node = None # Flag to auto add adviced operation values and time units auto_add = False + # Flag to auto add adviced operation values for fence agents + fa_advised_op_values = False default_promotable_meta = False comments = [] if isinstance(cli, str): @@ -867,11 +869,18 @@ def parse_cli_to_xml(cli, oldnode=None): utils.auto_convert_role = True if len(cli) >= 3 and cli[0] == "primitive" and cli[2].startswith("@"): auto_add = False + fa_advised_op_values = False default_promotable_meta = False else: auto_add = config.core.add_advised_op_values + fa_advised_op_values = config.core.fa_advised_op_values default_promotable_meta = True - node = parse.parse(cli, comments=comments, ignore_empty=False, auto_add=auto_add) + node = parse.parse( + cli, + comments=comments, + ignore_empty=False, + auto_add=auto_add, + fa_advised_op_values=fa_advised_op_values) if node is False: return None, None, None elif node is None: diff --git a/crmsh/config.py b/crmsh/config.py index 336cd5546..39dcc2a56 100644 --- a/crmsh/config.py +++ b/crmsh/config.py @@ -258,6 +258,7 @@ def get(self, value): 'no_ssh': opt_boolean('no'), 'OCF_1_1_SUPPORT': opt_boolean('no'), 'add_advised_op_values': opt_boolean('yes'), + 'fa_advised_op_values': opt_boolean('no'), 'obscure_pattern': opt_string('passw*') }, 'path': { diff --git a/crmsh/parse.py b/crmsh/parse.py index 34cbc0a2c..7e49ba904 100644 --- a/crmsh/parse.py +++ b/crmsh/parse.py @@ -170,13 +170,14 @@ def begin_dispatch(self, cmd, min_args=-1): self.begin(cmd, min_args=min_args) return self.match_dispatch(errmsg="Unknown command") - def do_parse(self, cmd, ignore_empty, auto_add): + def do_parse(self, cmd, ignore_empty, auto_add, fa_advised_op_values): """ Called by CliParser. Calls parse() Parsers should pass their return value through this method. """ self.ignore_empty = ignore_empty self.auto_add = auto_add + self.fa_advised_op_values = fa_advised_op_values out = self.parse(cmd) if self.has_tokens(): self.err("Unknown arguments: " + ' '.join(self._cmd[self._currtok:])) @@ -663,7 +664,10 @@ def add_default_advised_ops(self, out): """ if not self.auto_add or out.tag != "primitive": return - ra_inst = ra.RAInfo(out.get('class'), out.get('type'), out.get('provider')) + ra_class = out.get('class') + if ra_class == "stonith" and not self.fa_advised_op_values: + return + ra_inst = ra.RAInfo(ra_class, out.get('type'), out.get('provider')) ra_actions_dict = ra_inst.actions() if not ra_actions_dict: return @@ -1795,7 +1799,7 @@ def parse(self): return ret -def parse(s, comments=None, ignore_empty=True, auto_add=False): +def parse(s, comments=None, ignore_empty=True, auto_add=False, fa_advised_op_values=False): ''' Input: a list of tokens (or a CLI format string). Return: a cibobject @@ -1841,7 +1845,7 @@ def parse(s, comments=None, ignore_empty=True, auto_add=False): return False try: - ret = parser.do_parse(s, ignore_empty, auto_add) + ret = parser.do_parse(s, ignore_empty, auto_add, fa_advised_op_values) if ret is not None and len(comments) > 0: if ret.tag in constants.defaults_tags: xmlutil.stuff_comments(ret[0], comments) diff --git a/etc/crm.conf.in b/etc/crm.conf.in index 50bd86fd9..8d227992f 100644 --- a/etc/crm.conf.in +++ b/etc/crm.conf.in @@ -23,6 +23,9 @@ ; add_advised_op_values = yes ; no_ssh = no +; For fence agent, automatically add the advised values, default is no. +; fa_advised_op_values = no + ; set OCF_1_1_SUPPORT to yes is to fully turn on OCF 1.1 feature once the corresponding CIB detected. ; OCF_1_1_SUPPORT = yes From 14a500ee410e6d7c1c10d5757fa34e44c8d950cf Mon Sep 17 00:00:00 2001 From: xin liang Date: Thu, 29 Aug 2024 10:17:36 +0800 Subject: [PATCH 2/5] Dev: Add a new internal flag to control auto add time units on operation Add a specific flag 'auto_add_time_units', avoid mixing with the flag of auto add advised operation values for RA. --- crmsh/cibconfig.py | 7 ++++++- crmsh/parse.py | 14 ++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/crmsh/cibconfig.py b/crmsh/cibconfig.py index 24ae78855..bc70cfb89 100644 --- a/crmsh/cibconfig.py +++ b/crmsh/cibconfig.py @@ -859,6 +859,8 @@ def parse_cli_to_xml(cli, oldnode=None): auto_add = False # Flag to auto add adviced operation values for fence agents fa_advised_op_values = False + # Flag to auto add time units for operations + auto_add_time_units = False default_promotable_meta = False comments = [] if isinstance(cli, str): @@ -870,17 +872,20 @@ def parse_cli_to_xml(cli, oldnode=None): if len(cli) >= 3 and cli[0] == "primitive" and cli[2].startswith("@"): auto_add = False fa_advised_op_values = False + auto_add_time_units = False default_promotable_meta = False else: auto_add = config.core.add_advised_op_values fa_advised_op_values = config.core.fa_advised_op_values + auto_add_time_units = True default_promotable_meta = True node = parse.parse( cli, comments=comments, ignore_empty=False, auto_add=auto_add, - fa_advised_op_values=fa_advised_op_values) + fa_advised_op_values=fa_advised_op_values, + auto_add_time_units=auto_add_time_units) if node is False: return None, None, None elif node is None: diff --git a/crmsh/parse.py b/crmsh/parse.py index 7e49ba904..44e2725ba 100644 --- a/crmsh/parse.py +++ b/crmsh/parse.py @@ -170,7 +170,7 @@ def begin_dispatch(self, cmd, min_args=-1): self.begin(cmd, min_args=min_args) return self.match_dispatch(errmsg="Unknown command") - def do_parse(self, cmd, ignore_empty, auto_add, fa_advised_op_values): + def do_parse(self, cmd, ignore_empty, auto_add, fa_advised_op_values, auto_add_time_unit): """ Called by CliParser. Calls parse() Parsers should pass their return value through this method. @@ -178,6 +178,7 @@ def do_parse(self, cmd, ignore_empty, auto_add, fa_advised_op_values): self.ignore_empty = ignore_empty self.auto_add = auto_add self.fa_advised_op_values = fa_advised_op_values + self.auto_add_time_unit = auto_add_time_unit out = self.parse(cmd) if self.has_tokens(): self.err("Unknown arguments: " + ' '.join(self._cmd[self._currtok:])) @@ -798,7 +799,7 @@ def match_op(self, out, pfx='op'): if inst_attrs is not None: self.err(f"Attribute order error: {name} must appear before any instance attribute") value = nvp.get('value') - if name in ('interval', 'timeout') and self.auto_add: + if name in ('interval', 'timeout') and self.auto_add_time_unit: value = add_time_unit_if_needed(value) node.set(name, value) else: @@ -1799,7 +1800,12 @@ def parse(self): return ret -def parse(s, comments=None, ignore_empty=True, auto_add=False, fa_advised_op_values=False): +def parse(s, + comments=None, + ignore_empty=True, + auto_add=False, + fa_advised_op_values=False, + auto_add_time_units=False): ''' Input: a list of tokens (or a CLI format string). Return: a cibobject @@ -1845,7 +1851,7 @@ def parse(s, comments=None, ignore_empty=True, auto_add=False, fa_advised_op_val return False try: - ret = parser.do_parse(s, ignore_empty, auto_add, fa_advised_op_values) + ret = parser.do_parse(s, ignore_empty, auto_add, fa_advised_op_values, auto_add_time_units) if ret is not None and len(comments) > 0: if ret.tag in constants.defaults_tags: xmlutil.stuff_comments(ret[0], comments) From 0a188da1af9cbff05216777b6bfe8fa0cb878dfa Mon Sep 17 00:00:00 2001 From: xin liang Date: Thu, 29 Aug 2024 10:59:30 +0800 Subject: [PATCH 3/5] Dev: Rename the option 'add_advised_op_values' to 'ra_advised_op_values' Which is used to control the advised operations for resource agents, to distinct from the 'fa_advised_op_values' which is used to control the advised operations for fence agents. And rename relative internal variables. --- crmsh/cibconfig.py | 10 +++++----- crmsh/config.py | 2 +- crmsh/parse.py | 12 ++++++------ etc/crm.conf.in | 4 +++- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/crmsh/cibconfig.py b/crmsh/cibconfig.py index bc70cfb89..c1eb32900 100644 --- a/crmsh/cibconfig.py +++ b/crmsh/cibconfig.py @@ -855,8 +855,8 @@ def parse_cli_to_xml(cli, oldnode=None): output: XML, obj_type, obj_id """ node = None - # Flag to auto add adviced operation values and time units - auto_add = False + # Flag to auto add advised operation values for resource agents + ra_advised_op_values = False # Flag to auto add adviced operation values for fence agents fa_advised_op_values = False # Flag to auto add time units for operations @@ -870,12 +870,12 @@ def parse_cli_to_xml(cli, oldnode=None): else: # should be a pre-tokenized list utils.auto_convert_role = True if len(cli) >= 3 and cli[0] == "primitive" and cli[2].startswith("@"): - auto_add = False + ra_advised_op_values = False fa_advised_op_values = False auto_add_time_units = False default_promotable_meta = False else: - auto_add = config.core.add_advised_op_values + ra_advised_op_values = config.core.ra_advised_op_values fa_advised_op_values = config.core.fa_advised_op_values auto_add_time_units = True default_promotable_meta = True @@ -883,7 +883,7 @@ def parse_cli_to_xml(cli, oldnode=None): cli, comments=comments, ignore_empty=False, - auto_add=auto_add, + ra_advised_op_values=ra_advised_op_values, fa_advised_op_values=fa_advised_op_values, auto_add_time_units=auto_add_time_units) if node is False: diff --git a/crmsh/config.py b/crmsh/config.py index 39dcc2a56..697429a1a 100644 --- a/crmsh/config.py +++ b/crmsh/config.py @@ -257,7 +257,7 @@ def get(self, value): 'lock_timeout': opt_string('120'), 'no_ssh': opt_boolean('no'), 'OCF_1_1_SUPPORT': opt_boolean('no'), - 'add_advised_op_values': opt_boolean('yes'), + 'ra_advised_op_values': opt_boolean('yes'), 'fa_advised_op_values': opt_boolean('no'), 'obscure_pattern': opt_string('passw*') }, diff --git a/crmsh/parse.py b/crmsh/parse.py index 44e2725ba..697297f16 100644 --- a/crmsh/parse.py +++ b/crmsh/parse.py @@ -170,13 +170,13 @@ def begin_dispatch(self, cmd, min_args=-1): self.begin(cmd, min_args=min_args) return self.match_dispatch(errmsg="Unknown command") - def do_parse(self, cmd, ignore_empty, auto_add, fa_advised_op_values, auto_add_time_unit): + def do_parse(self, cmd, ignore_empty, ra_advised_op_values, fa_advised_op_values, auto_add_time_unit): """ Called by CliParser. Calls parse() Parsers should pass their return value through this method. """ self.ignore_empty = ignore_empty - self.auto_add = auto_add + self.ra_advised_op_values = ra_advised_op_values self.fa_advised_op_values = fa_advised_op_values self.auto_add_time_unit = auto_add_time_unit out = self.parse(cmd) @@ -663,7 +663,7 @@ def add_default_advised_ops(self, out): """ Add default operation actions advised values """ - if not self.auto_add or out.tag != "primitive": + if not self.ra_advised_op_values or out.tag != "primitive": return ra_class = out.get('class') if ra_class == "stonith" and not self.fa_advised_op_values: @@ -758,7 +758,7 @@ def match_container(self, out, _type): inst_attrs = xmlutil.child(container_node, name) # set meaningful id for port-mapping and storage-mapping # when the bundle is newly created - if self.auto_add: + if self.ra_advised_op_values: id_str = f"{bundle_id}_{name.replace('-', '_')}_{index}" inst_attrs.set('id', id_str) child_flag = True @@ -1803,7 +1803,7 @@ def parse(self): def parse(s, comments=None, ignore_empty=True, - auto_add=False, + ra_advised_op_values=False, fa_advised_op_values=False, auto_add_time_units=False): ''' @@ -1851,7 +1851,7 @@ def parse(s, return False try: - ret = parser.do_parse(s, ignore_empty, auto_add, fa_advised_op_values, auto_add_time_units) + ret = parser.do_parse(s, ignore_empty, ra_advised_op_values, fa_advised_op_values, auto_add_time_units) if ret is not None and len(comments) > 0: if ret.tag in constants.defaults_tags: xmlutil.stuff_comments(ret[0], comments) diff --git a/etc/crm.conf.in b/etc/crm.conf.in index 8d227992f..3f5ac5825 100644 --- a/etc/crm.conf.in +++ b/etc/crm.conf.in @@ -20,9 +20,11 @@ ; ignore_missing_metadata = no ; report_tool_options = ; lock_timeout = 120 -; add_advised_op_values = yes ; no_ssh = no +; For resource agent, automatically add the advised values, default is yes. +; ra_advised_op_values = yes + ; For fence agent, automatically add the advised values, default is no. ; fa_advised_op_values = no From c92adee93385d521e35b6cc377336f2762c70ac9 Mon Sep 17 00:00:00 2001 From: xin liang Date: Thu, 29 Aug 2024 11:26:50 +0800 Subject: [PATCH 4/5] Dev: run-functional-tests: Add 'fa_advised_op_values = yes' option for origin functional tests To avoid more changes for the expected test results --- test/run-functional-tests | 1 + 1 file changed, 1 insertion(+) diff --git a/test/run-functional-tests b/test/run-functional-tests index 5c3bca71d..1c1321715 100755 --- a/test/run-functional-tests +++ b/test/run-functional-tests @@ -424,6 +424,7 @@ adjust_test_case() { run_origin_regression_test() { CONFIG_COROSYNC_FLAG=0 setup_cluster "hanode1" + docker_exec "hanode1" "echo -e '[core]\nfa_advised_op_values = yes' > /etc/crm/crm.conf" docker_exec "hanode1" "sh /usr/share/crmsh/tests/regression.sh" return $? } From bb668201af5a6f6233e3ba3f46ee19f26e0d4b80 Mon Sep 17 00:00:00 2001 From: xin liang Date: Mon, 2 Sep 2024 14:38:01 +0800 Subject: [PATCH 5/5] Dev: Rename variables to make them look like boolean type From 'ra_advised_op_values' to 'has_ra_advised_op'; From 'fa_advised_op_values' to 'has_fa_advised_op' --- crmsh/cibconfig.py | 16 ++++++++-------- crmsh/config.py | 4 ++-- crmsh/parse.py | 18 +++++++++--------- etc/crm.conf.in | 4 ++-- test/run-functional-tests | 2 +- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/crmsh/cibconfig.py b/crmsh/cibconfig.py index c1eb32900..81acbe3c6 100644 --- a/crmsh/cibconfig.py +++ b/crmsh/cibconfig.py @@ -856,9 +856,9 @@ def parse_cli_to_xml(cli, oldnode=None): """ node = None # Flag to auto add advised operation values for resource agents - ra_advised_op_values = False + has_ra_advised_op = False # Flag to auto add adviced operation values for fence agents - fa_advised_op_values = False + has_fa_advised_op = False # Flag to auto add time units for operations auto_add_time_units = False default_promotable_meta = False @@ -870,21 +870,21 @@ def parse_cli_to_xml(cli, oldnode=None): else: # should be a pre-tokenized list utils.auto_convert_role = True if len(cli) >= 3 and cli[0] == "primitive" and cli[2].startswith("@"): - ra_advised_op_values = False - fa_advised_op_values = False + has_ra_advised_op = False + has_fa_advised_op = False auto_add_time_units = False default_promotable_meta = False else: - ra_advised_op_values = config.core.ra_advised_op_values - fa_advised_op_values = config.core.fa_advised_op_values + has_ra_advised_op = config.core.has_ra_advised_op + has_fa_advised_op = config.core.has_fa_advised_op auto_add_time_units = True default_promotable_meta = True node = parse.parse( cli, comments=comments, ignore_empty=False, - ra_advised_op_values=ra_advised_op_values, - fa_advised_op_values=fa_advised_op_values, + has_ra_advised_op=has_ra_advised_op, + has_fa_advised_op=has_fa_advised_op, auto_add_time_units=auto_add_time_units) if node is False: return None, None, None diff --git a/crmsh/config.py b/crmsh/config.py index 697429a1a..149683ed4 100644 --- a/crmsh/config.py +++ b/crmsh/config.py @@ -257,8 +257,8 @@ def get(self, value): 'lock_timeout': opt_string('120'), 'no_ssh': opt_boolean('no'), 'OCF_1_1_SUPPORT': opt_boolean('no'), - 'ra_advised_op_values': opt_boolean('yes'), - 'fa_advised_op_values': opt_boolean('no'), + 'has_ra_advised_op': opt_boolean('yes'), + 'has_fa_advised_op': opt_boolean('no'), 'obscure_pattern': opt_string('passw*') }, 'path': { diff --git a/crmsh/parse.py b/crmsh/parse.py index 697297f16..07c70ca1b 100644 --- a/crmsh/parse.py +++ b/crmsh/parse.py @@ -170,14 +170,14 @@ def begin_dispatch(self, cmd, min_args=-1): self.begin(cmd, min_args=min_args) return self.match_dispatch(errmsg="Unknown command") - def do_parse(self, cmd, ignore_empty, ra_advised_op_values, fa_advised_op_values, auto_add_time_unit): + def do_parse(self, cmd, ignore_empty, has_ra_advised_op, has_fa_advised_op, auto_add_time_unit): """ Called by CliParser. Calls parse() Parsers should pass their return value through this method. """ self.ignore_empty = ignore_empty - self.ra_advised_op_values = ra_advised_op_values - self.fa_advised_op_values = fa_advised_op_values + self.has_ra_advised_op = has_ra_advised_op + self.has_fa_advised_op = has_fa_advised_op self.auto_add_time_unit = auto_add_time_unit out = self.parse(cmd) if self.has_tokens(): @@ -663,10 +663,10 @@ def add_default_advised_ops(self, out): """ Add default operation actions advised values """ - if not self.ra_advised_op_values or out.tag != "primitive": + if not self.has_ra_advised_op or out.tag != "primitive": return ra_class = out.get('class') - if ra_class == "stonith" and not self.fa_advised_op_values: + if ra_class == "stonith" and not self.has_fa_advised_op: return ra_inst = ra.RAInfo(ra_class, out.get('type'), out.get('provider')) ra_actions_dict = ra_inst.actions() @@ -758,7 +758,7 @@ def match_container(self, out, _type): inst_attrs = xmlutil.child(container_node, name) # set meaningful id for port-mapping and storage-mapping # when the bundle is newly created - if self.ra_advised_op_values: + if self.has_ra_advised_op: id_str = f"{bundle_id}_{name.replace('-', '_')}_{index}" inst_attrs.set('id', id_str) child_flag = True @@ -1803,8 +1803,8 @@ def parse(self): def parse(s, comments=None, ignore_empty=True, - ra_advised_op_values=False, - fa_advised_op_values=False, + has_ra_advised_op=False, + has_fa_advised_op=False, auto_add_time_units=False): ''' Input: a list of tokens (or a CLI format string). @@ -1851,7 +1851,7 @@ def parse(s, return False try: - ret = parser.do_parse(s, ignore_empty, ra_advised_op_values, fa_advised_op_values, auto_add_time_units) + ret = parser.do_parse(s, ignore_empty, has_ra_advised_op, has_fa_advised_op, auto_add_time_units) if ret is not None and len(comments) > 0: if ret.tag in constants.defaults_tags: xmlutil.stuff_comments(ret[0], comments) diff --git a/etc/crm.conf.in b/etc/crm.conf.in index 3f5ac5825..9288911cc 100644 --- a/etc/crm.conf.in +++ b/etc/crm.conf.in @@ -23,10 +23,10 @@ ; no_ssh = no ; For resource agent, automatically add the advised values, default is yes. -; ra_advised_op_values = yes +; has_ra_advised_op = yes ; For fence agent, automatically add the advised values, default is no. -; fa_advised_op_values = no +; has_fa_advised_op = no ; set OCF_1_1_SUPPORT to yes is to fully turn on OCF 1.1 feature once the corresponding CIB detected. ; OCF_1_1_SUPPORT = yes diff --git a/test/run-functional-tests b/test/run-functional-tests index 1c1321715..9914a8c1e 100755 --- a/test/run-functional-tests +++ b/test/run-functional-tests @@ -424,7 +424,7 @@ adjust_test_case() { run_origin_regression_test() { CONFIG_COROSYNC_FLAG=0 setup_cluster "hanode1" - docker_exec "hanode1" "echo -e '[core]\nfa_advised_op_values = yes' > /etc/crm/crm.conf" + docker_exec "hanode1" "echo -e '[core]\nhas_fa_advised_op = yes' > /etc/crm/crm.conf" docker_exec "hanode1" "sh /usr/share/crmsh/tests/regression.sh" return $? }