Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2019-10-30 14:46:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new.2990 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Wed Oct 30 14:46:29 2019 rev:164 rq:743824 version:4.1.0+git.1572337494.6f2c8ea9 Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2019-09-30 16:03:03.100633369 +0200 +++ /work/SRC/openSUSE:Factory/.crmsh.new.2990/crmsh.changes 2019-10-30 14:46:46.358115561 +0100 @@ -1,0 +2,22 @@ +Tue Oct 29 08:30:11 UTC 2019 - [email protected] + +- Update to version 4.1.0+git.1572337494.6f2c8ea9: + * Doc: ui_node: do_maintenance: ask to remove maintenance attr from primitives + * Test: ui_node: do_maintenance: ask to remove maintenance attr from primitives + * Dev: ui_node: do_maintenance: ask to remove maintenance attr from primitives + +------------------------------------------------------------------- +Mon Oct 28 08:44:50 UTC 2019 - [email protected] + +- Update to version 4.1.0+git.1572251962.bc706121: + * unittest: add unittest for corosync.add_node_ucast + * Fix: corosync: reject append ipaddress to config file if already have(bsc#1127095, 1127096) + +------------------------------------------------------------------- +Mon Oct 21 08:09:02 UTC 2019 - [email protected] + +- Update to version 4.1.0+git.1571645029.57177c5d: + * Test: ui_resource: ask about ALL primitives when overriding attributes + * Dev: ui_resource: ask about ALL primitives when overriding attributes + +------------------------------------------------------------------- Old: ---- crmsh-4.1.0+git.1569593219.e357a9b9.tar.bz2 New: ---- crmsh-4.1.0+git.1572337494.6f2c8ea9.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.yL9dx8/_old 2019-10-30 14:46:47.122116373 +0100 +++ /var/tmp/diff_new_pack.yL9dx8/_new 2019-10-30 14:46:47.130116382 +0100 @@ -36,7 +36,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0-or-later Group: %{pkg_group} -Version: 4.1.0+git.1569593219.e357a9b9 +Version: 4.1.0+git.1572337494.6f2c8ea9 Release: 0 Url: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.yL9dx8/_old 2019-10-30 14:46:47.182116437 +0100 +++ /var/tmp/diff_new_pack.yL9dx8/_new 2019-10-30 14:46:47.182116437 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">e357a9b98c697d57d5ef33b489a1b59d02dea77a</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">6f2c8ea926f61f2ce99fcfbefa401d51feaddbf1</param></service></servicedata> \ No newline at end of file ++++++ crmsh-4.1.0+git.1569593219.e357a9b9.tar.bz2 -> crmsh-4.1.0+git.1572337494.6f2c8ea9.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/bootstrap.py new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/bootstrap.py --- old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/bootstrap.py 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/bootstrap.py 2019-10-29 09:24:54.000000000 +0100 @@ -1748,7 +1748,10 @@ break print("") invoke("rm -f /var/lib/heartbeat/crm/* /var/lib/pacemaker/cib/*") - corosync.add_node_ucast(ringXaddr_res) + try: + corosync.add_node_ucast(ringXaddr_res) + except ValueError as e: + warn(e) csync2_update(corosync.conf()) invoke("ssh -o StrictHostKeyChecking=no root@{} corosync-cfgtool -R".format(seed_host)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/corosync.py new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/corosync.py --- old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/corosync.py 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/corosync.py 2019-10-29 09:24:54.000000000 +0100 @@ -386,6 +386,15 @@ f = open(conf()).read() p = Parser(f) + # to check if the same IP already configured + exist_iplist = [] + for path in p.all_paths(): + if re.search('nodelist.node.ring[0-9]*_addr', path): + exist_iplist.extend(p.get_all(path)) + for ip in IParray: + if ip in exist_iplist: + raise ValueError("IP {} was already configured".format(ip)) + node_id = get_free_nodeid(p) node_value = [] for i, addr in enumerate(IParray): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/ui_node.py new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/ui_node.py --- old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/ui_node.py 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/ui_node.py 2019-10-29 09:24:54.000000000 +0100 @@ -5,13 +5,121 @@ from . import config from . import command from . import completers as compl +from . import constants from . import ui_utils from . import utils from . import xmlutil from .msg import common_err, syntax_err, no_prog_err, common_info, common_warn +from .msg import common_debug from .cliformat import cli_nvpairs, nvpairs2list from . import term +from .cibconfig import cib_factory +from .ui_resource import rm_meta_attribute +def remove_redundant_attrs(objs, attr, conflicting_attr = None): + """ + Remove attr from all resources_tags in the cib.xml + """ + # Override the resources on the node + for r in objs: + for meta_set in xmlutil.get_set_nodes(r, "meta_attributes", create=False): + a = xmlutil.get_attr_in_set(meta_set, attr) + if a is not None and \ + (config.core.manage_children == "always" or \ + (config.core.manage_children == "ask" and + utils.ask("'%s' attribute already exists in %s. Remove it?" % + (attr, r.get("id"))))): + common_debug("force remove meta attr %s from %s" % + (attr, r.get("id"))) + xmlutil.rmnode(a) + xmlutil.xml_processnodes(r, xmlutil.is_emptynvpairs, xmlutil.rmnodes) + if conflicting_attr is not None: + a = xmlutil.get_attr_in_set(meta_set, conflicting_attr) + if a is not None and \ + (config.core.manage_children == "always" or \ + (config.core.manage_children == "ask" and + utils.ask("'%s' conflicts with '%s' in %s. Remove it?" % + (conflicting_attr, attr, r.get("id"))))): + common_debug("force remove meta attr %s from %s" % + (conflicting_attr, r.get("id"))) + xmlutil.rmnode(a) + xmlutil.xml_processnodes(r, xmlutil.is_emptynvpairs, xmlutil.rmnodes) + +def get_resources_on_nodes(nodes, resources_tags): + prefix = "cli-prefer-" + exclude = [str(x.node.get("id")).replace(prefix,"") for x in cib_factory.cib_objects + if x.obj_type == "location" and x.node.get("node") not in nodes] + + resources = [x.node for x in cib_factory.cib_objects + if x.obj_type in resources_tags and x.obj_id not in exclude] + return resources + +def update_xml_node(cluster_node_name, attr, value): + ''' + xml_node.attr := value + + Besides, it asks the user if he wants to + 1) remove both the attr and conflicting_attr + in primitives, groups and clones + 2) remove the conflicting attribute in the node itself + ''' + + node_obj = cib_factory.find_node(cluster_node_name) + if node_obj is None: + common_err("CIB is not valid!") + return False + + common_debug("update_xml_node: %s" % (node_obj.obj_id)) + + xml_node = node_obj.node + node_obj.set_updated() + + conflicting_attr = '' + if 'maintenance' == attr: + conflicting_attr = 'is-managed' + if 'is-managed' == attr: + conflicting_attr = 'maintenance' + + # Get all primitive, group and clone resources currently running on the cluster_node_name + objs = get_resources_on_nodes([cluster_node_name], [ "primitive", "group", "clone"]) + + # Ask the user to remove the 'attr' attributes on those primitives, groups and clones + remove_redundant_attrs(objs, attr, conflicting_attr) + + # Remove the node conflicting attribute + nvpairs = xml_node.xpath("./instance_attributes/nvpair[@name='%s']" % (conflicting_attr)) + if len(nvpairs) > 0 and \ + utils.ask("'%s' conflicts with '%s' in %s. Remove it?" % + (conflicting_attr, attr, xml_node.get("uname"))): + for nvpair in nvpairs: + xmlutil.rmnode(nvpair) + xmlutil.xml_processnodes(xml_node, xmlutil.is_emptynvpairs, xmlutil.rmnodes) + + # Set the node attribute + nvpairs = xml_node.xpath("./instance_attributes/nvpair[@name='%s']" % (attr)) + if len(nvpairs) > 0: + for nvpair in nvpairs: + nvpair.set("value", value) + else: + for n in xmlutil.get_set_instace_attributes(xml_node, create=True): + xmlutil.set_attr(n, attr, value) + return True + +def set_node_attr(cluster_node_name, attr_name, value, commit=True): + """ + Set an attribute for a node + """ + if not update_xml_node(cluster_node_name, attr_name, value): + common_err("Failed to update node attributes for %s" % (cluster_node_name)) + return False + + if not commit: + return True + + if not cib_factory.commit(): + common_err("Failed to commit updates to %s" % (cluster_node_name)) + return False + return True def _oneline(s): 'join s into a single line of space-separated tokens' @@ -218,7 +326,8 @@ node = utils.this_node() if not utils.is_name_sane(node): return False - return utils.ext_cmd(self.node_maint % (node, "on")) == 0 + return self._commit_node_attr(context, node, "maintenance", "true") + @command.wait @command.completers(compl.nodes) @@ -347,6 +456,17 @@ return ui_utils.manage_attr(context.get_command_name(), self.node_status, node, cmd, attr, value) + def _commit_node_attr(self, context, node_name, attr_name, value): + """ + Perform change to resource + """ + if not utils.is_name_sane(node_name): + return False + commit = not cib_factory.has_cib_changed() + if not commit: + context.info("Currently editing the CIB, changes will not be committed") + return set_node_attr(node_name, attr_name, value, commit=commit) + def do_server(self, context, *nodes): """ usage: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/ui_resource.py new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/ui_resource.py --- old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/ui_resource.py 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/ui_resource.py 2019-10-29 09:24:54.000000000 +0100 @@ -30,20 +30,6 @@ (xmlutil.is_child_rsc(c) and not c.getparent().tag == "group"): rm_meta_attribute(c, attr, l, force_children=force_children) - -def get_children_with_different_attr(node, attr, value): - l = [] - for p in node.xpath(".//primitive"): - diff_attr = False - for meta_set in xmlutil.get_set_nodes(p, "meta_attributes", create=False): - p_value = xmlutil.get_attr_value(meta_set, attr) - if p_value is not None and p_value != value: - diff_attr = True - break - if diff_attr: - l.append(p) - return l - def get_children_with_attr(node, attr): l = [] for p in node.xpath(".//primitive"): @@ -83,8 +69,8 @@ common_debug("force remove meta attr %s from %s" % (conflicting_attr, c.get("id"))) rm_meta_attribute(c, conflicting_attr, nvpair_l, force_children=True) - # remove attributes with different values - odd_children = get_children_with_different_attr(target_node, attr, value) + # remove the same attributes from all children (if wanted) + odd_children = get_children_with_attr(target_node, attr) for c in odd_children: if config.core.manage_children == "always" or \ (config.core.manage_children == "ask" and diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/xmlutil.py new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/xmlutil.py --- old/crmsh-4.1.0+git.1569593219.e357a9b9/crmsh/xmlutil.py 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/crmsh/xmlutil.py 2019-10-29 09:24:54.000000000 +0100 @@ -1226,6 +1226,20 @@ l.append(elem) return l +def get_set_instace_attributes(e, create=False): + ''' + Return instance attributes set nodes (create one if requested) + ''' + l = [c for c in e.iterchildren("instance_attributes")] + if l: + return l + if create: + from . import idmgmt + elem = etree.SubElement(e, "instance_attributes", id="") + elem.set("id", "nodes-"+e.attrib["id"]) + l.append(elem) + return l + _checker = doctestcompare.LXMLOutputChecker() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/doc/crm.8.adoc new/crmsh-4.1.0+git.1572337494.6f2c8ea9/doc/crm.8.adoc --- old/crmsh-4.1.0+git.1569593219.e357a9b9/doc/crm.8.adoc 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/doc/crm.8.adoc 2019-10-29 09:24:54.000000000 +0100 @@ -2413,7 +2413,9 @@ Set the node status to maintenance. This is equivalent to the cluster-wide `maintenance-mode` property but puts just one node -into the maintenance mode. +into the maintenance mode. If there are maintenaned resources on +the node, the user will be proposed to remove the maintenance +property from them. The node parameter defaults to the node where the command is run. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/doc/website-v1/man-2.0.adoc new/crmsh-4.1.0+git.1572337494.6f2c8ea9/doc/website-v1/man-2.0.adoc --- old/crmsh-4.1.0+git.1569593219.e357a9b9/doc/website-v1/man-2.0.adoc 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/doc/website-v1/man-2.0.adoc 2019-10-29 09:24:54.000000000 +0100 @@ -2101,7 +2101,9 @@ Set the node status to maintenance. This is equivalent to the cluster-wide `maintenance-mode` property but puts just one node -into the maintenance mode. +into the maintenance mode. If there are maintenaned resources on +the node, the user will be proposed to remove the maintenance +property from them. The node parameter defaults to the node where the command is run. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/doc/website-v1/man-3.adoc new/crmsh-4.1.0+git.1572337494.6f2c8ea9/doc/website-v1/man-3.adoc --- old/crmsh-4.1.0+git.1569593219.e357a9b9/doc/website-v1/man-3.adoc 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/doc/website-v1/man-3.adoc 2019-10-29 09:24:54.000000000 +0100 @@ -2362,7 +2362,9 @@ Set the node status to maintenance. This is equivalent to the cluster-wide `maintenance-mode` property but puts just one node -into the maintenance mode. +into the maintenance mode. If there are maintenaned resources on +the node, the user will be proposed to remove the maintenance +property from them. The node parameter defaults to the node where the command is run. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/node new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/node --- old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/node 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/node 2019-10-29 09:24:54.000000000 +0100 @@ -3,7 +3,11 @@ %setenv showobj=node1 node standby node1 node online node1 -node maintenance node1 +configure primitive p5 Dummy +configure group g0 p5 +resource maintenance g0 +resource maintenance p5 +-F node maintenance node1 node ready node1 node attribute node1 set a1 "1 2 3" node attribute node1 show a1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/node.exp new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/node.exp --- old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/node.exp 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/node.exp 2019-10-29 09:24:54.000000000 +0100 @@ -45,8 +45,12 @@ </configuration> </cib> -.TRY node maintenance node1 -.EXT crm_attribute -t nodes -N 'node1' -n maintenance -v 'on' +.TRY configure primitive p5 Dummy +.EXT crm_resource --show-metadata ocf:heartbeat:Dummy +.EXT crm_resource --show-metadata ocf:pacemaker:Dummy +.EXT crm_resource --show-metadata stonith:null +.EXT stonithd metadata +.EXT crm_resource --show-metadata ocf:heartbeat:Delay .INP: configure .INP: _regtest on .INP: show xml node1 @@ -58,7 +62,89 @@ <node uname="node1" id="node1"> <instance_attributes id="nodes-node1"> <nvpair id="nodes-node1-standby" name="standby" value="off"/> - <nvpair id="nodes-node1-maintenance" name="maintenance" value="on"/> + </instance_attributes> + </node> + </nodes> + <resources/> + <constraints/> + </configuration> +</cib> + +.TRY configure group g0 p5 +.INP: configure +.INP: _regtest on +.INP: show xml node1 +<?xml version="1.0" ?> +<cib> + <configuration> + <crm_config/> + <nodes> + <node uname="node1" id="node1"> + <instance_attributes id="nodes-node1"> + <nvpair id="nodes-node1-standby" name="standby" value="off"/> + </instance_attributes> + </node> + </nodes> + <resources/> + <constraints/> + </configuration> +</cib> + +.TRY resource maintenance g0 +.INP: configure +.INP: _regtest on +.INP: show xml node1 +<?xml version="1.0" ?> +<cib> + <configuration> + <crm_config/> + <nodes> + <node uname="node1" id="node1"> + <instance_attributes id="nodes-node1"> + <nvpair id="nodes-node1-standby" name="standby" value="off"/> + </instance_attributes> + </node> + </nodes> + <resources/> + <constraints/> + </configuration> +</cib> + +.TRY resource maintenance p5 +.INP: configure +.INP: _regtest on +.INP: show xml node1 +<?xml version="1.0" ?> +<cib> + <configuration> + <crm_config/> + <nodes> + <node uname="node1" id="node1"> + <instance_attributes id="nodes-node1"> + <nvpair id="nodes-node1-standby" name="standby" value="off"/> + </instance_attributes> + </node> + </nodes> + <resources/> + <constraints/> + </configuration> +</cib> + +.TRY -F node maintenance node1 +INFO: 'maintenance' attribute already exists in p5. Remove it? [YES] +INFO: 'maintenance' attribute already exists in g0. Remove it? [YES] +.INP: configure +.INP: _regtest on +.INP: show xml node1 +<?xml version="1.0" ?> +<cib> + <configuration> + <crm_config/> + <nodes> + <node uname="node1" id="node1"> + <instance_attributes id="nodes-node1"> + <nvpair id="nodes-node1-standby" name="standby" value="off"/> + <nvpair id="nodes-node1-maintenance" name="maintenance" value="true"/> </instance_attributes> </node> </nodes> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/resource new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/resource --- old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/resource 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/resource 2019-10-29 09:24:54.000000000 +0100 @@ -78,3 +78,7 @@ %setenv showobj=g1 -F resource manage g1 resource start p5 +%setenv showobj=p5 +-F resource maintenance p5 on +%setenv showobj=g1 +-F resource maintenance g1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/resource.exp new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/resource.exp --- old/crmsh-4.1.0+git.1569593219.e357a9b9/test/testcases/resource.exp 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/testcases/resource.exp 2019-10-29 09:24:54.000000000 +0100 @@ -712,11 +712,7 @@ <nvpair id="cg-meta_attributes-target-role" name="target-role" value="Started"/> </meta_attributes> <group id="g"> - <primitive id="p0" class="ocf" provider="pacemaker" type="Dummy"> - <meta_attributes id="p0-meta_attributes"> - <nvpair id="p0-meta_attributes-target-role" name="target-role" value="Started"/> - </meta_attributes> - </primitive> + <primitive id="p0" class="ocf" provider="pacemaker" type="Dummy"/> <primitive id="p3" class="ocf" provider="pacemaker" type="Dummy"/> </group> </clone> @@ -1105,6 +1101,60 @@ </meta_attributes> <primitive id="p5" class="ocf" provider="heartbeat" type="Dummy"> <meta_attributes id="p5-meta_attributes"> + <nvpair id="p5-meta_attributes-target-role" name="target-role" value="Started"/> + </meta_attributes> + </primitive> + </group> + </resources> + <constraints/> + </configuration> +</cib> + +.SETENV showobj=p5 +.TRY -F resource maintenance p5 on +.INP: configure +.INP: _regtest on +.INP: show xml p5 +<?xml version="1.0" ?> +<cib> + <configuration> + <crm_config/> + <nodes/> + <resources> + <group id="g1"> + <meta_attributes id="g1-meta_attributes-0"> + <nvpair id="g1-meta_attributes-0-is-managed" name="is-managed" value="true"/> + </meta_attributes> + <primitive id="p5" class="ocf" provider="heartbeat" type="Dummy"> + <meta_attributes id="p5-meta_attributes"> + <nvpair id="p5-meta_attributes-target-role" name="target-role" value="Started"/> + <nvpair id="p5-meta_attributes-maintenance" name="maintenance" value="true"/> + </meta_attributes> + </primitive> + </group> + </resources> + <constraints/> + </configuration> +</cib> + +.SETENV showobj=g1 +.TRY -F resource maintenance g1 +INFO: 'maintenance' conflicts with 'is-managed' attribute. Remove 'is-managed' for resource g1? [YES] +.INP: configure +.INP: _regtest on +.INP: show xml g1 +<?xml version="1.0" ?> +<cib> + <configuration> + <crm_config/> + <nodes/> + <resources> + <group id="g1"> + <meta_attributes id="g1-meta_attributes"> + <nvpair id="g1-meta_attributes-maintenance" name="maintenance" value="true"/> + </meta_attributes> + <primitive id="p5" class="ocf" provider="heartbeat" type="Dummy"> + <meta_attributes id="p5-meta_attributes"> <nvpair id="p5-meta_attributes-target-role" name="target-role" value="Started"/> </meta_attributes> </primitive> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.1.0+git.1569593219.e357a9b9/test/unittests/test_corosync.py new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/unittests/test_corosync.py --- old/crmsh-4.1.0+git.1569593219.e357a9b9/test/unittests/test_corosync.py 2019-09-27 16:06:59.000000000 +0200 +++ new/crmsh-4.1.0+git.1572337494.6f2c8ea9/test/unittests/test_corosync.py 2019-10-29 09:24:54.000000000 +0100 @@ -92,6 +92,27 @@ _valid(p) self.assertEqual(p.count('nodelist.node'), nid - 1) + def test_add_node_ucast(self): + from crmsh.corosync import add_node_ucast, get_values + + os.environ["COROSYNC_MAIN_CONFIG_FILE"] = os.path.join(os.path.dirname(__file__), 'corosync.conf.2') + + exist_iplist = get_values('nodelist.node.ring0_addr') + try: + add_node_ucast(['10.10.10.11']) + except ValueError: + self.fail("corosync.add_node_ucast raised ValueError unexpectedly!") + now_iplist = get_values('nodelist.node.ring0_addr') + self.assertEqual(len(exist_iplist) + 1, len(now_iplist)) + self.assertTrue('10.10.10.11' in get_values('nodelist.node.ring0_addr')) + + # bsc#1127095, 1127096; address 10.10.10.11 already exist + with self.assertRaises(ValueError) as err: + add_node_ucast(['10.10.10.11']) + self.assertEqual("IP 10.10.10.11 was already configured", str(err.exception)) + now_iplist = get_values('nodelist.node.ring0_addr') + self.assertEqual(len(exist_iplist) + 1, len(now_iplist)) + def test_add_node_nodelist(self): from crmsh.corosync import make_section, make_value, get_free_nodeid
