diff --git a/crmsh/ui_resource.py b/crmsh/ui_resource.py index dbc97a8069..548a1aa44a 100644 --- a/crmsh/ui_resource.py +++ b/crmsh/ui_resource.py @@ -287,6 +287,8 @@ def _commit_meta_attrs(self, context, resources, name, value): for rsc in resources: if not utils.is_name_sane(rsc): return False + if not xmlutil.RscState().is_managed(rsc): + context.warning("Resource {} is unmanaged".format(rsc)) commit = not cib_factory.has_cib_changed() if not commit: context.info("Currently editing the CIB, changes will not be committed") diff --git a/crmsh/xmlutil.py b/crmsh/xmlutil.py index 7b35e8650c..243ac23d48 100644 --- a/crmsh/xmlutil.py +++ b/crmsh/xmlutil.py @@ -17,7 +17,7 @@ from . import userdir from .utils import add_sudo, str2file, str2tmp, get_boolean from .utils import get_stdout, stdout2list, crm_msec, crm_time_cmp -from .utils import olist, get_cib_in_use, get_tempdir, to_ascii +from .utils import olist, get_cib_in_use, get_tempdir, to_ascii, running_on def xmlparse(f): @@ -251,8 +251,18 @@ def is_managed(self, ident): attr = get_attr_value(self.prop_elem, "maintenance-mode") if attr and is_xs_boolean_true(attr): return False - # then check the rsc is-managed meta attribute + # then check if all nodes are in maintenance + if all([is_node_in_maintenance(node) for node in listnodes()]): + return False + # then check if node running this resource is in maintenance + if any([is_node_in_maintenance(node) for node in running_on(ident)]): + return False rsc_meta_node = get_rsc_meta_node(rsc_node) + # then check the rsc maintenance meta attribute + attr = get_attr_value(rsc_meta_node, "maintenance") + if attr and is_xs_boolean_true(attr): + return False + # then check the rsc is-managed meta attribute attr = get_attr_value(rsc_meta_node, "is-managed") if attr: return is_xs_boolean_true(attr) @@ -293,6 +303,20 @@ def can_delete(self, ident): return not (self.is_running(ident) and not self.is_group(ident) and self.is_managed(ident)) +def is_node_in_maintenance(node_name): + """ + Detect if node is in maintenance + """ + if node_name not in listnodes(): + common_err("Node {} not exist".format(node_name)) + return + cib = cibdump2elem("configuration") + node_entry = cib.xpath(".//*[@uname=\"{}\"]".format(node_name))[0] + attr_entry = get_child_nvset_node(node_entry, attr_set="instance_attributes") + attr = get_attr_value(attr_entry, "maintenance") + return is_xs_boolean_true(attr) if attr else False + + def resources_xml(): return cibdump2elem("resources")