Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2019-05-10 09:19:11 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new.5148 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Fri May 10 09:19:11 2019 rev:156 rq:701570 version:4.0.0+git.1557307618.dc73b57b Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2019-03-26 15:45:25.168082051 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new.5148/crmsh.changes 2019-05-10 09:19:15.732415788 +0200 @@ -1,0 +2,11 @@ +Wed May 08 09:47:11 UTC 2019 - [email protected] + +- Update to version 4.0.0+git.1557307618.dc73b57b: + * medium: cibconfig: Sanitize CIB for patching (bsc#1127716) + * high: cibconfig: Use correct CIB as patch base (bsc#1127716) + * medium: parse: Detect and error on illegal ordering of op attributes (bsc#1129210) + * medium: utils: Handle sysconfig values containing = (bsc#1129317) + * low: hb_report: collect output of "sbd dump" and "sbd list"(bsc#1129383) + * low: msg: add timestamp for DEBUG messages(bsc#1129380) + +------------------------------------------------------------------- Old: ---- crmsh-4.0.0+git.1552985860.56f2db3a.tar.bz2 New: ---- crmsh-4.0.0+git.1557307618.dc73b57b.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.IWVPDR/_old 2019-05-10 09:19:17.220418089 +0200 +++ /var/tmp/diff_new_pack.IWVPDR/_new 2019-05-10 09:19:17.244418126 +0200 @@ -36,7 +36,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0-or-later Group: %{pkg_group} -Version: 4.0.0+git.1552985860.56f2db3a +Version: 4.0.0+git.1557307618.dc73b57b Release: 0 Url: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.IWVPDR/_old 2019-05-10 09:19:17.700418831 +0200 +++ /var/tmp/diff_new_pack.IWVPDR/_new 2019-05-10 09:19:17.720418862 +0200 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">56f2db3ab753c7df0554158b718faa33ecefb081</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">dc73b57b255d9b2a2fbf6cca0c459a63c2c76624</param></service></servicedata> \ No newline at end of file ++++++ crmsh-4.0.0+git.1552985860.56f2db3a.tar.bz2 -> crmsh-4.0.0+git.1557307618.dc73b57b.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/.travis.yml new/crmsh-4.0.0+git.1557307618.dc73b57b/.travis.yml --- old/crmsh-4.0.0+git.1552985860.56f2db3a/.travis.yml 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/.travis.yml 2019-05-08 11:26:58.000000000 +0200 @@ -4,23 +4,70 @@ services: - docker +stages: + - test + - delivery + - submit + env: global: - CC_TEST_REPORTER_ID=a2579335b631ec35473874d7bb4fe983025c0287cea89c9dc34c35f98ee3963d -before_script: - - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - - chmod +x ./cc-test-reporter - - ./cc-test-reporter before-build - -before_install: - - docker pull krig/crmsh:latest - -script: - - docker run -t -v "$(pwd):/app" krig/crmsh /bin/sh -c "systemctl start dbus; cd /app; ./test/run-in-travis.sh" - -after_failure: - - sudo cat $TRAVIS_BUILD_DIR/crmtestout/regression.out $TRAVIS_BUILD_DIR/crmtestout/crm.* - -after_script: - - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT +jobs: + include: + - stage: test + before_script: + - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + - chmod +x ./cc-test-reporter + - ./cc-test-reporter before-build + + before_install: + - docker pull krig/crmsh:latest + + script: + - docker run -t -v "$(pwd):/app" krig/crmsh /bin/sh -c "systemctl start dbus; cd /app; ./test/run-in-travis.sh" + + after_failure: + - sudo cat $TRAVIS_BUILD_DIR/crmtestout/regression.out $TRAVIS_BUILD_DIR/crmtestout/crm.* + + after_script: + - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT + + - stage: delivery + if: type != pull_request AND branch = master + env: + - FOLDER=/package + - PACKAGE_NAME=crmsh + + before_install: + - docker pull shap/continuous_deliver:latest + + script: + - | + docker run -t -v "$(pwd):/package" \ + -e OBS_USER=$OBS_USER \ + -e OBS_PASS=$OBS_PASS \ + -e FOLDER=$FOLDER \ + -e OBS_PROJECT=$OBS_PROJECT \ + -e PACKAGE_NAME=$PACKAGE_NAME \ + shap/continuous_deliver \ + /bin/bash -c "cd /package;/scripts/upload.sh" + + - stage: submit + if: type != pull_request AND branch = master + env: + - PACKAGE_NAME=crmsh + + before_install: + - docker pull shap/continuous_deliver:latest + + script: + - | + docker run -t -v "$(pwd):/package" \ + -e OBS_USER=$OBS_USER \ + -e OBS_PASS=$OBS_PASS \ + -e OBS_PROJECT=$OBS_PROJECT \ + -e PACKAGE_NAME=$PACKAGE_NAME \ + -e TARGET_PROJECT=$TARGET_PROJECT \ + shap/continuous_deliver \ + /bin/bash -c "cd /package;/scripts/submit.sh" \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/README.md new/crmsh-4.0.0+git.1557307618.dc73b57b/README.md --- old/crmsh-4.0.0+git.1552985860.56f2db3a/README.md 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/README.md 2019-05-08 11:26:58.000000000 +0200 @@ -84,6 +84,12 @@ chmod +x .git/hooks/pre-commit ``` +## Contributing + +You can contribute following the standard `fork -> clone -> change -> pull request` Github process for code changes. The pull request process is integrated with the [openSUSE Build Service](https://build.opensuse.org/), and as soon as it gets merged, a new RPM package is built on [network:ha-clustering:Unstable](https://build.opensuse.org/project/show/network:ha-clustering:Unstable) and a `submit request` is created to the _crmsh_ package maintainers at [network:ha-clustering:Factory](https://build.opensuse.org/project/show/network:ha-clustering:Factory). + +The commit messages are used to create the changelog, so, please, include relevant and comprehensive messages on your commits. + ## Community * Bugs and issues can be reported at the [crmsh issues @ Github.com](https://github.com/clusterlabs/crmsh/issues) page. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/cibconfig.py new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/cibconfig.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/cibconfig.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/cibconfig.py 2019-05-08 11:26:58.000000000 +0200 @@ -40,12 +40,13 @@ from .xmlutil import sanity_check_nvpairs, merge_nodes, op2list, mk_rsc_type, is_resource from .xmlutil import stuff_comments, is_comment, is_constraint, read_cib, processing_sort_cli from .xmlutil import find_operation, get_rsc_children_ids, is_primitive, referenced_resources -from .xmlutil import cibdump2elem, processing_sort, get_rsc_ref_ids, merge_tmpl_into_prim +from .xmlutil import cibdump2tmp, cibdump2elem, processing_sort, get_rsc_ref_ids, merge_tmpl_into_prim from .xmlutil import remove_id_used_attributes, get_top_cib_nodes from .xmlutil import merge_attributes, is_cib_element, sanity_check_meta from .xmlutil import is_simpleconstraint, is_template, rmnode, is_defaults, is_live_cib from .xmlutil import get_rsc_operations, delete_rscref, xml_equals, lookup_node, RscState from .xmlutil import cibtext2elem, is_related, check_id_ref, xml_tostring +from .xmlutil import sanitize_cib_for_patching from .cliformat import get_score, nvpairs2list, abs_pos_score, cli_acl_roleref, nvpair_format from .cliformat import cli_nvpair, cli_acl_rule, rsc_set_constraint, get_kind, head_id_format from .cliformat import simple_rsc_constraint, cli_rule, cli_format @@ -2679,8 +2680,7 @@ # now increase the epoch by 1 self.bump_epoch() self._set_cib_attributes(self.cib_elem) - cib_s = xml_tostring(self.cib_orig, pretty_print=True) - tmpf = str2tmp(cib_s, suffix=".xml") + tmpf = cibdump2tmp(filterfn=sanitize_cib_for_patching) if not tmpf or not ensure_sudo_readable(tmpf): return False tmpfiles.add(tmpf) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/main.py new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/main.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/main.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/main.py 2019-05-08 11:26:58.000000000 +0200 @@ -360,6 +360,8 @@ err_buf.reset_lineno() options.batch = True user_args = parse_options() + if config.core.debug: + print(utils.debug_timestamp()) term.init() if options.profile: return profile_run(context, user_args) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/parse.py new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/parse.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/parse.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/parse.py 2019-05-08 11:26:58.000000000 +0200 @@ -692,11 +692,19 @@ inst_attrs = None for nvp in all_attrs: if nvp.get('name') in valid_attrs: + if inst_attrs is not None: + self.err("Attribute order error: {} must appear before any instance attribute".format(nvp.get('name'))) node.set(nvp.get('name'), nvp.get('value')) else: if inst_attrs is None: inst_attrs = xmlutil.child(node, 'instance_attributes') inst_attrs.append(nvp) + if inst_attrs is not None: + node.append(inst_attrs) + for attr_list in self.match_attr_lists({'op_params': 'instance_attributes', + 'op_meta': 'meta_attributes'}, + implicit_initial='op_params'): + node.append(attr_list) out.append(node) def match_operations(self, out, match_id): @@ -784,64 +792,6 @@ xmlutil.maybe_set(out, 'provider', cpt[1]) xmlutil.maybe_set(out, 'type', cpt[2]) - def match_op(self, out, pfx='op'): - """ - op <optype> [<n>=<v> ...] - - to: - <op name="monitor" timeout="30" interval="10" id="p_mysql-monitor-10"> - <instance_attributes id="p_mysql-monitor-10-instance_attributes"> - <nvpair name="depth" value="0" id="p_mysql-monitor-10-instance_attributes-depth"/> - </instance_attributes> - </op> - """ - self.match('op') - op_type = self.match_identifier() - all_attrs = self.match_nvpairs(minpairs=0) - node = xmlutil.new('op', name=op_type) - if not any(nvp.get('name') == 'interval' for nvp in all_attrs): - all_attrs.append(xmlutil.nvpair('interval', '0')) - valid_attrs = validator.op_attributes() - inst_attrs = None - nvpairs_missed = 0 - for nvp in all_attrs: - if nvp.get('name') in valid_attrs: - node.set(nvp.get('name'), nvp.get('value')) - else: - nvpairs_missed += 1 - for i in range(nvpairs_missed): - self.rewind() - for attr_list in self.match_attr_lists({'op_params': 'instance_attributes', - 'op_meta': 'meta_attributes'}, - implicit_initial='op_params'): - node.append(attr_list) - out.append(node) - - def match_operations(self, out, match_id): - from .cibconfig import cib_factory - - def is_op(): - return self.has_tokens() and self.current_token().lower() == 'op' - if match_id: - self.match('operations') - node = xmlutil.child(out, 'operations') - if match_id: - self.match_idspec() - match_id = self.matched(1)[1:].lower() - idval = self.matched(2) - if match_id == 'id-ref': - idval = cib_factory.resolve_id_ref('operations', idval) - - node.set(match_id, idval) - - # The ID assignment skips the operations node if possible, - # so we need to pass the prefix (id of the owner node) - # to match_op - pfx = out.get('id') or 'op' - - while is_op(): - self.match_op(node, pfx=pfx) - def parse(self, cmd): return self.begin_dispatch(cmd, min_args=2) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/utils.py new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/utils.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/utils.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/utils.py 2019-05-08 11:26:58.000000000 +0200 @@ -1880,14 +1880,15 @@ Reads a sysconfig file into a dict """ ret = {} - vre = re.compile(r"(\S+)\s*=\s*(.*)") if os.path.isfile(sysconfig_file): for line in open(sysconfig_file).readlines(): if line.lstrip().startswith('#'): continue - m = vre.match(line) - if m: - ret[m.group(1)] = unquote(m.group(2)) + try: + key, val = line.split("=", 1) + ret[key] = unquote(val) + except ValueError: + pass return ret @@ -1896,7 +1897,6 @@ Set the values in the sysconfig file, updating the variables if they exist already, appending them if not. """ - vre = re.compile(r"(\S+)\s*=\s*(.*)") outp = "" if os.path.isfile(sysconfig_file): for line in open(sysconfig_file).readlines(): @@ -1904,16 +1904,19 @@ outp += line else: matched = False - m = vre.match(line) - if m: - for k, v in values.items(): - if k == m.group(1): - matched = True - outp += '%s=%s\n' % (k, doublequote(v)) - del values[k] - break + try: + key, _ = line.split("=", 1) + for k, v in values.items(): + if k == key: + matched = True + outp += '%s=%s\n' % (k, doublequote(v)) + del values[k] + break if not matched: outp += line + except ValueError: + outp += line + for k, v in values.items(): outp += '%s=%s\n' % (k, doublequote(v)) str2file(outp, sysconfig_file) @@ -2159,4 +2162,8 @@ return [] +def debug_timestamp(): + return datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') + + # vim:ts=4:sw=4:et: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/xmlutil.py new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/xmlutil.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/crmsh/xmlutil.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/crmsh/xmlutil.py 2019-05-08 11:26:58.000000000 +0200 @@ -87,9 +87,17 @@ return None -def cibdump2tmp(): +def cibdump2tmp(filterfn=None): try: _, outp, _ = sudocall(cib_dump) + if filterfn is not None: + try: + cib_elem = etree.fromstring(outp) + except etree.ParseError as msg: + common_err(msg) + return None + filterfn(cib_elem) + outp = etree.tostring(cib_elem, pretty_print=True) if outp is not None: return str2tmp(outp) except IOError as msg: @@ -667,6 +675,7 @@ def sanitize_cib(doc): + xml_processnodes(doc, is_status_node, rmnodes) # xml_processnodes(doc, true, printid) # xml_processnodes(doc, is_emptynvpairs, rmnodes) @@ -678,6 +687,17 @@ xml_processnodes(doc, true, remove_text) xmltraverse(doc, drop_attr_defaults) +def sanitize_cib_for_patching(doc): + """ + Custom version of sanitize_cib which + doesn't sort container children, to use + for processing the original CIB when + generating a patch to apply using crm_diff. + """ + xml_processnodes(doc, is_status_node, rmnodes) + xml_processnodes(doc, is_entity, rmnodes) + xml_processnodes(doc, true, remove_dflt_attrs) + xml_processnodes(doc, true, remove_text) def is_simpleconstraint(node): return len(node.xpath("resource_set/resource_ref")) == 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/hb_report/constants.py new/crmsh-4.0.0+git.1557307618.dc73b57b/hb_report/constants.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/hb_report/constants.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/hb_report/constants.py 2019-05-08 11:26:58.000000000 +0200 @@ -139,5 +139,6 @@ SYSSTATS_F = "sysstats.txt" TIME_F = "time.txt" OCFS2_F = "ocfs2.txt" +SBD_F = "sbd.txt" # vim:ts=4:sw=4:et: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/hb_report/utillib.py new/crmsh-4.0.0+git.1557307618.dc73b57b/hb_report/utillib.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/hb_report/utillib.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/hb_report/utillib.py 2019-05-08 11:26:58.000000000 +0200 @@ -1467,6 +1467,16 @@ if os.path.exists(constants.SBDCONF): shutil.copy2(constants.SBDCONF, constants.WORKDIR) + if not which("sbd"): + return + sbd_f = os.path.join(constants.WORKDIR, constants.SBD_F) + cmd = ". {};export SBD_DEVICE;{};{}".format(constants.SBDCONF, "sbd dump", "sbd list") + with open(sbd_f, "w") as f: + _, out = crmutils.get_stdout(cmd) + f.write("\n\n#=====[ Command ] ==========================#\n") + f.write("# %s\n"%(cmd)) + f.write(out) + def sed_inplace(filename, pattern, repl): out_string = "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/test/unittests/test_parse.py new/crmsh-4.0.0+git.1557307618.dc73b57b/test/unittests/test_parse.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/test/unittests/test_parse.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/test/unittests/test_parse.py 2019-05-08 11:26:58.000000000 +0200 @@ -368,6 +368,10 @@ self.assertEqual(out.get('role'), None) self.assertEqual(out.get('interval'), '60m') + out = self._parse('primitive rsc_dummy1 Dummy op monitor interval=10 OCF_CHECK_LEVEL=10 timeout=60') + # incorrect ordering of attributes + self.assertFalse(out) + def test_acl(self): out = self._parse('role user-1 error') self.assertFalse(out) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.0.0+git.1552985860.56f2db3a/test/unittests/test_utils.py new/crmsh-4.0.0+git.1557307618.dc73b57b/test/unittests/test_utils.py --- old/crmsh-4.0.0+git.1552985860.56f2db3a/test/unittests/test_utils.py 2019-03-19 09:57:40.000000000 +0100 +++ new/crmsh-4.0.0+git.1557307618.dc73b57b/test/unittests/test_utils.py 2019-05-08 11:26:58.000000000 +0200 @@ -8,6 +8,7 @@ from itertools import chain from crmsh import utils from crmsh import config +from crmsh import tmpfiles def test_systeminfo(): @@ -136,3 +137,32 @@ assert (utils.ip_in_network('2001:db8::1', '2001:db8::2/64') is True) assert utils.get_ipv6_network("2002:db8::2/64") == "2002:db8::" + + +def test_parse_sysconfig(): + """ + bsc#1129317: Fails on this line + + FW_SERVICES_ACCEPT_EXT="0/0,tcp,22,,hitcount=3,blockseconds=60,recentname=ssh" + """ + s = ''' +FW_SERVICES_ACCEPT_EXT="0/0,tcp,22,,hitcount=3,blockseconds=60,recentname=ssh" +''' + + fd, fname = tmpfiles.create() + with open(fname, 'w') as f: + f.write(s) + sc = utils.parse_sysconfig(fname) + assert ("FW_SERVICES_ACCEPT_EXT" in sc) + +def test_sysconfig_set(): + s = ''' +FW_SERVICES_ACCEPT_EXT="0/0,tcp,22,,hitcount=3,blockseconds=60,recentname=ssh" +''' + fd, fname = tmpfiles.create() + with open(fname, 'w') as f: + f.write(s) + utils.sysconfig_set(fname, FW_SERVICES_ACCEPT_EXT="foo=bar", FOO="bar") + sc = utils.parse_sysconfig(fname) + assert (sc.get("FW_SERVICES_ACCEPT_EXT") == "foo=bar") + assert (sc.get("FOO") == "bar")
