Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2014-04-20 11:36:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2014-04-09 13:12:08.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.crmsh.new/crmsh.changes 2014-04-20 11:36:52.000000000 +0200 @@ -1,0 +2,16 @@ +Fri Apr 11 07:58:21 UTC 2014 - [email protected] + +- hb_report: pcmk lib changed permissions (bnc#872958) +- history: Use subsecond precision if possible (bnc#872932) +- history: set colours for all nodes found (bnc#872936) +- upstream: 2.0.0-18-ga957470950b6 + +------------------------------------------------------------------- +Wed Apr 9 12:37:17 UTC 2014 - [email protected] + +- parse: Support cib object tags (fate#315101) +- cibconfig: Support filename-style globs in show/edit (bnc#864346) +- Support Pacemaker 1.3 schema +- upstream: 2.0.0-12-g60ed9131ec43 + +------------------------------------------------------------------- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.c272Ki/_old 2014-04-20 11:36:53.000000000 +0200 +++ /var/tmp/diff_new_pack.c272Ki/_new 2014-04-20 11:36:53.000000000 +0200 @@ -41,7 +41,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0+ Group: %{pkg_group} -Version: 2.0+git5 +Version: 2.0+git18 Release: %{?crmsh_release}%{?dist} Url: http://crmsh.github.io Source0: crmsh.tar.bz2 ++++++ crmsh.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/doc/crm.8.txt new/crmsh/doc/crm.8.txt --- old/crmsh/doc/crm.8.txt 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/doc/crm.8.txt 2014-04-11 09:31:00.000000000 +0200 @@ -2717,6 +2717,24 @@ op_defaults record-pending=true ............... +[[cmdhelp_configure_tag,Define resource tags]] +==== `tag` + +Define a resource tag. A tag is an id referring to one or more +resources, without implying any constraints between the tagged +resources. This can be useful for grouping conceptually related +resources. + +Usage: +............... +tag <tag-name>: <rsc> [<rsc> ...] +............... +Example: +............... +tag web: p-webserver p-vip +............... + + [[cmdhelp_configure_schema,set or display current CIB RNG schema]] ==== `schema` diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/hb_report/ha_cf_support.sh new/crmsh/hb_report/ha_cf_support.sh --- old/crmsh/hb_report/ha_cf_support.sh 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/hb_report/ha_cf_support.sh 2014-04-11 09:31:00.000000000 +0200 @@ -76,7 +76,7 @@ cat<<EOF d $HA_VARLIB 0755 root root d $HA_VARLIB/ccm 0750 hacluster haclient -d $PCMK_LIB 0755 root root +d $PCMK_LIB 0750 hacluster haclient d $PE_STATE_DIR 0750 hacluster haclient d $CIB_DIR 0750 hacluster haclient EOF diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/hb_report/openais_conf_support.sh new/crmsh/hb_report/openais_conf_support.sh --- old/crmsh/hb_report/openais_conf_support.sh 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/hb_report/openais_conf_support.sh 2014-04-11 09:31:00.000000000 +0200 @@ -90,7 +90,7 @@ } essential_files() { cat<<EOF -d $PCMK_LIB 0755 root root +d $PCMK_LIB 0750 hacluster haclient d $PE_STATE_DIR 0750 hacluster haclient d $CIB_DIR 0750 hacluster haclient EOF diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/cibconfig.py new/crmsh/modules/cibconfig.py --- old/crmsh/modules/cibconfig.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/cibconfig.py 2014-04-11 09:31:00.000000000 +0200 @@ -20,6 +20,7 @@ import os import sys import re +import fnmatch import time import config from singletonmixin import Singleton @@ -824,6 +825,7 @@ "utilization": "utilization", "operations": "operations", "op": "op", + "tag": "tag", } @@ -1752,7 +1754,8 @@ for enode in self.node.xpath("rule/expression"): if enode.get("attribute") == "#uname": uname = enode.get("value") - if uname and uname.lower() not in [id.lower() for id in cib_factory.node_id_list()]: + ids = [i.lower() for i in cib_factory.node_id_list()] + if uname and uname.lower() not in ids: common_warn("%s: referenced node %s does not exist" % (self.obj_id, uname)) rc = 1 return rc @@ -2141,6 +2144,29 @@ headnode.append(n) remove_id_used_attributes(oldnode) return headnode + + +class CibTag(CibObject): + + def _repr_cli_head(self, fmt): + s = cli_display.keyword('tag') + id_ = cli_display.id(self.obj_id) + return "%s %s:" % (s, id_) + + def _repr_cli_child(self, c, fmt): + return c.get('id') + + def _cli_list2node(self, cli_list, oldnode): + """ + cli_list: [[tag] <id> [<rsc>, <rsc>...]] + out: <tag id="<id>"><obj_ref id="<rsc>">...</tag> + """ + tagid = cli_list[0][1][0][1] + tag = etree.Element('tag', id=tagid) + for rsc in cli_list[1]: + etree.SubElement(tag, 'obj_ref', id=rsc) + return tag + # ################################################################ @@ -2182,6 +2208,7 @@ "fencing-topology": ("fencing_topology", CibFencingOrder, "configuration"), "acl_role": ("role", CibAcl, "acls"), "acl_user": ("user", CibAcl, "acls"), + "tag": ("tag", CibTag, "tags"), } # generate a translation cli -> tag @@ -2212,7 +2239,7 @@ self.last_commit_time = 0 # internal (just not to produce silly messages) self._no_constraint_rm_msg = False - self.supported_cib_re = "^pacemaker-1[.][012]$" + self.supported_cib_re = "^pacemaker-1[.][0123]$" def is_cib_sane(self): # try to initialize @@ -2616,16 +2643,23 @@ self._clean_state() id_store.clear() - def find_object(self, obj_id): - "Find an object for id." + def find_objects(self, obj_id): + "Find objects for id (can be a wildcard-glob)." + matchfn = lambda x: fnmatch.fnmatch(x, obj_id) + objs = [] for obj in self.cib_objects: - if obj.obj_id == obj_id: - return obj + if matchfn(obj.obj_id): + objs.append(obj) # special case for Heartbeat nodes which have id # different from uname - if obj.obj_type == "node" and \ - obj.node.get("uname") == obj_id: - return obj + elif obj.obj_type == "node" and matchfn(obj.node.get("uname")): + objs.append(obj) + return objs + + def find_object(self, obj_id): + objs = self.find_objects(obj_id) + if len(objs) > 0: + return objs[0] return None # @@ -2895,10 +2929,10 @@ elif spec.startswith("type:"): obj_set |= set(self.get_elems_on_type(spec)) else: - obj = self.find_object(spec) - if obj: + objs = self.find_objects(spec) + for obj in objs: obj_set.add(obj) - else: + if len(objs) == 0: no_object_err(spec) rc = False return rc, obj_set diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/cibobjects.py new/crmsh/modules/cibobjects.py --- old/crmsh/modules/cibobjects.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/cibobjects.py 2014-04-11 09:31:00.000000000 +0200 @@ -397,3 +397,15 @@ def _to_list(self): return listfmt('[[% [[id %]]] [raw %]]', self.type, self.id, self.raw) + + +class Tag(Expr): + def __init__(self): + Expr.__init__(self) + self.id = None + self.resources = [] + + def _to_list(self): + ret = listfmt('[[tag [[id %]]]]', self.id) + ret.append(self.resources) + return ret diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/pacemaker.py new/crmsh/modules/pacemaker.py --- old/crmsh/modules/pacemaker.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/pacemaker.py 2014-04-11 09:31:00.000000000 +0200 @@ -30,6 +30,7 @@ "pacemaker-1.0": ("rng", "pacemaker-1.0.rng"), "pacemaker-1.1": ("rng", "pacemaker-1.1.rng"), "pacemaker-1.2": ("rng", "pacemaker-1.2.rng"), + "pacemaker-1.3": ("rng", "pacemaker-1.3.rng"), } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/parse.py new/crmsh/modules/parse.py --- old/crmsh/modules/parse.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/parse.py 2014-04-11 09:31:00.000000000 +0200 @@ -26,7 +26,7 @@ from msg import common_err, syntax_err from cibobjects import Primitive, RscTemplate, Group, Clone, Master from cibobjects import Location, Colocation, Order -from cibobjects import Monitor, Node, Property, RscTicket +from cibobjects import Monitor, Node, Property, RscTicket, Tag from cibobjects import FencingTopology, ACLRight, Role, User, RawXML @@ -805,6 +805,28 @@ return out +class TagParser(BaseParser): + _TAG_RE = re.compile(r"([^:]+):$") + + def can_parse(self): + return ('tag',) + + def parse(self, cmd): + self.begin(cmd, min_args=2) + self.match('tag') + self.match(self._TAG_RE) + tagname = self.matched(1) + resources = [] + while self.has_tokens(): + resources.append(self.match_resource()) + if not resources: + self.err("Expected at least one resource") + out = Tag() + out.id = tagname + out.resources = resources + return out + + class AclParser(BaseParser): _ACL_RIGHT_RE = re.compile(r'(%s)$' % ('|'.join(vars.acl_rule_names)), re.IGNORECASE) _ROLE_REF_RE = re.compile(r'role:(.+)$', re.IGNORECASE) @@ -1174,7 +1196,8 @@ PropertyParser, FencingOrderParser, AclParser, - RawXMLParser) + RawXMLParser, + TagParser) def _xml_lex(self, s): try: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/report.py new/crmsh/modules/report.py --- old/crmsh/modules/report.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/report.py 2014-04-11 09:31:00.000000000 +0200 @@ -72,13 +72,13 @@ def syslog_ts(s): try: # strptime defaults year to 1900 (sigh) + # strptime returns a time_struct tm = time.strptime(' '.join([YEAR] + s.split()[0:3]), "%Y %b %d %H:%M:%S") - return time.mktime(tm) + return datetime.datetime.fromtimestamp(time.mktime(tm)) except: # try the rfc5424 try: - tm = parse_time(s.split()[0]) - return time.mktime(tm.timetuple()) + return parse_time(s.split()[0]) except Exception: common_debug("malformed line: %s" % s) return None @@ -1038,7 +1038,7 @@ def set_node_colors(self): i = 0 - for n in self.cibnode_l: + for n in self.get_nodes(): self.nodecolor[n] = self.nodecolors[i] i = (i+1) % len(self.nodecolors) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/ui_configure.py new/crmsh/modules/ui_configure.py --- old/crmsh/modules/ui_configure.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/ui_configure.py 2014-04-11 09:31:00.000000000 +0200 @@ -758,6 +758,11 @@ status""" return self.__conf_object(context.get_command_name(), *args) + @command.skill_level('administrator') + @command.completers_repeating(compl.null, top_rsc_tmpl_id_list) + def do_tag(self, context, *args): + return self.__conf_object(context.get_command_name(), *args) + @command.skill_level('expert') @command.completers_repeating(_rsc_id_list) def do_rsctest(self, context, *args): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/ui_resource.py new/crmsh/modules/ui_resource.py --- old/crmsh/modules/ui_resource.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/ui_resource.py 2014-04-11 09:31:00.000000000 +0200 @@ -90,7 +90,16 @@ else: for n in xmlutil.get_set_nodes(target_node, "meta_attributes", 1): xmlutil.set_attr(n, attr, value) - return xmlutil.commit_rsc(target_node) + return True + + +def set_deep_meta_attr_tag(tag, attr, value): + """ + tag: an etree tag node + TODO: make transactional (shadow CIB?) + """ + return all(set_deep_meta_attr(attr, value, ref.get('id')) + for ref in tag.xpath("./obj_ref")) def set_deep_meta_attr(attr, value, rsc_id): @@ -109,10 +118,15 @@ if target_node is None: common_error("resource %s does not exist" % rsc_id) return False + + if target_node.tag == 'tag': + return set_deep_meta_attr_tag(target_node, attr, value) if not (target_node.tag == "primitive" and target_node.getparent().tag == "group"): target_node = xmlutil.get_topmost_rsc(target_node) - return set_deep_meta_attr_node(target_node, attr, value) + if not set_deep_meta_attr_node(target_node, attr, value): + return False + return xmlutil.commit_rsc(target_node) def cleanup_resource(rsc, node=''): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/utils.py new/crmsh/modules/utils.py --- old/crmsh/modules/utils.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/utils.py 2014-04-11 09:31:00.000000000 +0200 @@ -380,7 +380,8 @@ cmd = "(%s; rm -f %s)" % (cmd, dotfile) if options.regression_tests: print ".EXT", cmd - subprocess.Popen(cmd, shell=True, bufsize=0, stdin=None, stdout=None, stderr=None, close_fds=True) + subprocess.Popen(cmd, shell=True, bufsize=0, + stdin=None, stdout=None, stderr=None, close_fds=True) common_info("starting %s to show %s" % (config.core.dotty, desc)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/modules/xmlutil.py new/crmsh/modules/xmlutil.py --- old/crmsh/modules/xmlutil.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/modules/xmlutil.py 2014-04-11 09:31:00.000000000 +0200 @@ -887,7 +887,7 @@ def filter_on_type(cl, obj_type): - if type(cl[0]) == type([]): + if isinstance(cl[0], list): l = [cli_list for cli_list in cl if cli_list[0][0] == obj_type] if config.core.sort_elements: l.sort(cmp=cmp) @@ -958,7 +958,8 @@ ''' if not cl: return [] - return nodes_cli(cl) + templates_cli(cl) + primitives_cli(cl) + groups_cli(cl) + mss_cli(cl) + clones_cli(cl) \ + return nodes_cli(cl) + templates_cli(cl) + primitives_cli(cl) \ + + groups_cli(cl) + mss_cli(cl) + clones_cli(cl) \ + constraints_cli(cl) + fencing_topology_cli(cl) + properties_cli(cl) \ + ops_cli(cl) + acls_cli(cl) @@ -1311,18 +1312,18 @@ if a.tag != b.tag: return fail("tags differ: %s != %s" % (a.tag, b.tag)) - if a.attrib != b.attrib: + elif a.attrib != b.attrib: return fail("attributes differ: %s != %s" % (a.attrib, b.attrib)) - if safe_strip(a.text) != safe_strip(b.text): + elif safe_strip(a.text) != safe_strip(b.text): return fail("text differ %s != %s" % (repr(a.text), repr(b.text))) - if safe_strip(a.tail) != safe_strip(b.tail): + elif safe_strip(a.tail) != safe_strip(b.tail): return fail("tails differ: %s != %s" % (a.tail, b.tail)) - if len(a) != len(b): + elif len(a) != len(b): return fail("number of children differ") + elif len(a) == 0: + return True sorted_children = zip(sorted(a, key=sortby), sorted(b, key=sortby)) - if sorted_children: - return all(xml_equals_unordered(a, b) for a, b in sorted_children) - return True + return all(xml_equals_unordered(a, b) for a, b in sorted_children) def xml_equals(n, m, show=False): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh/test/unittests/test_parse.py new/crmsh/test/unittests/test_parse.py --- old/crmsh/test/unittests/test_parse.py 2014-04-07 22:28:33.000000000 +0200 +++ new/crmsh/test/unittests/test_parse.py 2014-04-11 09:31:00.000000000 +0200 @@ -362,6 +362,19 @@ out = self.parser.parse('fencing_topology vbox4: stonith-vbox3-1-off,stonith-vbox3-2-off,stonith-vbox3-1-on,stonith-vbox3-2-on') self.assertEqual(1, len(out.levels)) + def test_tag(self): + out = self.parser.parse('tag tag1: one two three') + self.assertEqual(out.id, 'tag1') + self.assertEqual(out.resources, ['one', 'two', 'three']) + self.assertEqual([['tag', [['id', 'tag1']]], ['one', 'two', 'three']], + out.to_list()) + + out = self.parser.parse('tag tag1:') + self.assertFalse(out) + + out = self.parser.parse('tag tag1:: foo') + self.assertFalse(out) + def _parse_lines(self, lines): out = [] for line in lines2cli(lines): -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
