Skip to content

Commit f31b7f6

Browse files
committed
Dev: Parsing resource meta attributes dynamically
With the latest pacemaker version (since 2.1.8), crmsh can get the resource meta attributes by parsing the output of `crm_resource --list-options=primitive --output-as=xml` command. The benefit of this approach: - Avoid hardcoding the resource meta attributes - Provide help info at interactive mode for each meta attribute
1 parent ea6db17 commit f31b7f6

File tree

4 files changed

+44
-6
lines changed

4 files changed

+44
-6
lines changed

crmsh/cibconfig.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from . import crm_gv
2626
from . import ui_utils
2727
from . import userdir
28-
from .ra import get_ra, get_properties_list, get_pe_meta, get_properties_meta, RAInfo
28+
from .ra import get_ra, get_properties_list, get_pe_meta, get_properties_meta, RAInfo, get_resource_meta_list
2929
from .utils import ext_cmd, safe_open_w, pipe_string, safe_close_w, crm_msec
3030
from .utils import ask, lines2cli, olist
3131
from .utils import page_string, str2tmp, ensure_sudo_readable
@@ -1571,7 +1571,7 @@ def check_sanity(self):
15711571
if self.node is None: # eh?
15721572
logger.error("%s: no xml (strange)", self.obj_id)
15731573
return utils.get_check_rc()
1574-
rc3 = sanity_check_meta(self.obj_id, self.node, constants.rsc_meta_attributes)
1574+
rc3 = sanity_check_meta(self.obj_id, self.node, get_resource_meta_list())
15751575
if self.obj_type == "primitive":
15761576
r_node = reduce_primitive(self.node)
15771577
if r_node is None:
@@ -1681,7 +1681,7 @@ def check_sanity(self):
16811681
if self.node is None: # eh?
16821682
logger.error("%s: no xml (strange)", self.obj_id)
16831683
return utils.get_check_rc()
1684-
l = constants.rsc_meta_attributes
1684+
l = get_resource_meta_list()
16851685
if self.obj_type == "clone":
16861686
l += constants.clone_meta_attributes
16871687
elif self.obj_type == "ms":
@@ -2045,7 +2045,7 @@ def check_sanity(self):
20452045
elif self.obj_type == "op_defaults":
20462046
l = schema.get('attr', 'op', 'a')
20472047
elif self.obj_type == "rsc_defaults":
2048-
l = constants.rsc_meta_attributes
2048+
l = get_resource_meta_list()
20492049
rc = sanity_check_nvpairs(self.obj_id, self.node, l)
20502050
return rc
20512051

crmsh/ra.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,23 @@ def get_properties_list():
228228
return []
229229

230230

231+
@utils.memoize
232+
def get_resource_meta():
233+
resource_meta = utils.get_resource_metadata()
234+
if resource_meta:
235+
return RAInfo("resource_meta", None, meta_string=resource_meta)
236+
return None
237+
238+
239+
@utils.memoize
240+
def get_resource_meta_list():
241+
try:
242+
return list(get_resource_meta().params().keys())
243+
# use legacy code to get the resource metadata list
244+
except:
245+
return constants.rsc_meta_attributes
246+
247+
231248
def prog_meta(prog):
232249
'''
233250
Do external program metadata.

crmsh/ui_configure.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,14 @@ def _prim_meta_completer(agent, args):
238238
completing = args[-1]
239239
if completing == 'meta':
240240
return ['meta']
241+
if completing.endswith('='):
242+
if len(completing) > 1 and options.interactive:
243+
topic = completing[:-1]
244+
CompletionHelp.help(topic, agent.meta_parameter(topic), args)
245+
return []
241246
if '=' in completing:
242247
return []
243-
return utils.filter_keys(constants.rsc_meta_attributes, args)
248+
return utils.filter_keys(ra.get_resource_meta_list(), args)
244249

245250

246251
def _prim_op_completer(agent, args):
@@ -304,6 +309,11 @@ def _property_completer(args):
304309
return _prim_params_completer(agent, args)
305310

306311

312+
def _rsc_meta_completer(args):
313+
agent = ra.get_resource_meta()
314+
return _prim_meta_completer(agent, args)
315+
316+
307317
def primitive_complete_complex(args):
308318
'''
309319
This completer depends on the content of the line, i.e. on
@@ -334,6 +344,8 @@ def primitive_complete_complex(args):
334344
if last_keyw is None:
335345
return []
336346

347+
if last_keyw == 'meta':
348+
agent = ra.get_resource_meta()
337349
complete_results = completers_set[last_keyw](agent, args)
338350
if len(args) > 4 and '=' in args[-1]:
339351
return complete_results + keywords
@@ -1125,7 +1137,7 @@ def do_property(self, context, *args):
11251137
return self.__conf_object(context.get_command_name(), *args)
11261138

11271139
@command.skill_level('administrator')
1128-
@command.completers_repeating(_prim_meta_completer)
1140+
@command.completers_repeating(_rsc_meta_completer)
11291141
def do_rsc_defaults(self, context, *args):
11301142
"usage: rsc_defaults [$id=<set_id>] <option>=<value>"
11311143
return self.__conf_object(context.get_command_name(), *args)

crmsh/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ def get_cluster_option_metadata(show_xml=True) -> str:
194194
return None
195195

196196

197+
def get_resource_metadata(show_xml=True) -> str:
198+
output_type = "xml" if show_xml else "text"
199+
cmd = f"crm_resource --list-options=primitive --all --output-as={output_type}"
200+
rc, out, _ = ShellUtils().get_stdout_stderr(cmd)
201+
if rc == 0 and out:
202+
return out
203+
return None
204+
205+
197206
def pacemaker_20_daemon(new, old):
198207
"helper to discover renamed pacemaker daemons"
199208
if is_program(new):

0 commit comments

Comments
 (0)