Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2021-03-19 16:43:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new.2401 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Fri Mar 19 16:43:25 2021 rev:204 rq:880013 version:4.3.0+git.20210319.b0adc897 Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2021-03-15 10:56:19.869349531 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new.2401/crmsh.changes 2021-03-19 16:43:26.382136955 +0100 @@ -1,0 +2,27 @@ +Fri Mar 19 04:26:16 UTC 2021 - xli...@suse.com + +- Update to version 4.3.0+git.20210319.b0adc897: + * Fix: update verion and author (bsc#1183689) + +------------------------------------------------------------------- +Wed Mar 17 01:31:04 UTC 2021 - xli...@suse.com + +- Update to version 4.3.0+git.20210317.5ee12f25: + * Dev: behave: adjust functional test for configuring qdevice on interactive mode + * Dev: unittest: unit test codes for configuring qdevice on interactive mode + * Dev: bootstrap: enable configuring qdevice on interactive mode + +------------------------------------------------------------------- +Mon Mar 15 09:59:59 UTC 2021 - xli...@suse.com + +- Update to version 4.3.0+git.20210315.5d07d43e: + * Dev: behave: change the test case for failcount behavior change + * Fix: ui_resource: change return code and error to warning for some unharmful actions(bsc#1180332) + +------------------------------------------------------------------- +Mon Mar 15 09:32:43 UTC 2021 - xli...@suse.com + +- Update to version 4.3.0+git.20210315.fae29920: + * Dev: README: change the build status link in README + +------------------------------------------------------------------- Old: ---- crmsh-4.3.0+git.20210311.c2e8856c.tar.bz2 New: ---- crmsh-4.3.0+git.20210319.b0adc897.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.3EIOwR/_old 2021-03-19 16:43:27.134137970 +0100 +++ /var/tmp/diff_new_pack.3EIOwR/_new 2021-03-19 16:43:27.138137975 +0100 @@ -36,7 +36,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0-or-later Group: %{pkg_group} -Version: 4.3.0+git.20210311.c2e8856c +Version: 4.3.0+git.20210319.b0adc897 Release: 0 URL: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.3EIOwR/_old 2021-03-19 16:43:27.170138019 +0100 +++ /var/tmp/diff_new_pack.3EIOwR/_new 2021-03-19 16:43:27.174138024 +0100 @@ -9,6 +9,6 @@ </service> <service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">e0bb141ccc848feedda7cab741fc035f62f19bc5</param> + <param name="changesrevision">b0adc897a8c08e5b6cab39c2981367f811b1492f</param> </service> </servicedata> \ No newline at end of file ++++++ crmsh-4.3.0+git.20210311.c2e8856c.tar.bz2 -> crmsh-4.3.0+git.20210319.b0adc897.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/README.md new/crmsh-4.3.0+git.20210319.b0adc897/README.md --- old/crmsh-4.3.0+git.20210311.c2e8856c/README.md 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/README.md 2021-03-19 05:13:08.000000000 +0100 @@ -1,6 +1,7 @@ # crmsh -[](https://travis-ci.org/ClusterLabs/crmsh) +[](https://github.com/ClusterLabs/crmsh/actions/workflows/crmsh-ci.yml) + ## Introduction diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/configure.ac new/crmsh-4.3.0+git.20210319.b0adc897/configure.ac --- old/crmsh-4.3.0+git.20210311.c2e8856c/configure.ac 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/configure.ac 2021-03-19 05:13:08.000000000 +0100 @@ -8,7 +8,7 @@ AC_PREREQ([2.53]) -AC_INIT([crmsh],[4.2.0],[us...@clusterlabs.org]) +AC_INIT([crmsh],[4.3.0],[us...@clusterlabs.org]) AC_ARG_WITH(version, [ --with-version=version Override package version (if you're a packager needing to pretend) ], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/bootstrap.py new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/bootstrap.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/bootstrap.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/bootstrap.py 2021-03-19 05:13:08.000000000 +0100 @@ -1873,15 +1873,42 @@ return QdevicePolicy.QDEVICE_RESTART +def configure_qdevice_interactive(): + """ + Configure qdevice on interactive mode + """ + if _context.yes_to_all or not confirm("Do you want to configure QDevice?"): + return + qnetd_addr = prompt_for_string("HOST or IP of the QNetd server to be used") + if not qnetd_addr: + error("Address of QNetd is required") + qdevice_port = prompt_for_string("TCP PORT of QNetd server", default=5403) + qdevice_algo = prompt_for_string("QNetd decision ALGORITHM (ffsplit/lms)", default="ffsplit") + qdevice_tie_breaker = prompt_for_string("QNetd TIE_BREAKER (lowest/highest/valid node id)", default="lowest") + qdevice_tls = prompt_for_string("Whether using TLS on QDevice/QNetd (on/off/required)", default="on") + qdevice_heuristics = prompt_for_string("Heuristics COMMAND to run with absolute path; For multiple commands, use \";\" to separate") + qdevice_heuristics_mode = prompt_for_string("MODE of operation of heuristics (on/sync/off)", default="sync") if qdevice_heuristics else None + _context.qdevice_inst = corosync.QDevice( + qnetd_addr, + port=qdevice_port, + algo=qdevice_algo, + tie_breaker=qdevice_tie_breaker, + tls=qdevice_tls, + cmds=qdevice_heuristics, + mode=qdevice_heuristics_mode) + _context.qdevice_inst.valid_attr() + + def init_qdevice(): """ Setup qdevice and qnetd service """ + if not _context.qdevice_inst: + configure_qdevice_interactive() # If don't want to config qdevice, return if not _context.qdevice_inst: utils.disable_service("corosync-qdevice.service") return - if _context.stage == "qdevice": utils.check_all_nodes_reachable() _context.qdevice_reload_policy = evaluate_qdevice_quorum_effect(QDEVICE_ADD) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/corosync.py new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/corosync.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/corosync.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/corosync.py 2021-03-19 05:13:08.000000000 +0100 @@ -278,9 +278,15 @@ if not utils.valid_port(self.port): raise ValueError("invalid qdevice port range(1024 - 65535)") - if self.tie_breaker not in ["lowest", "highest"] and not utils.valid_nodeid(self.tie_breaker): + if self.algo not in ("ffsplit", "lms"): + raise ValueError("invalid ALGORITHM choice: '{}' (choose from 'ffsplit', 'lms')".format(self.algo)) + + if self.tie_breaker not in ("lowest", "highest") and not utils.valid_nodeid(self.tie_breaker): raise ValueError("invalid qdevice tie_breaker(lowest/highest/valid_node_id)") + if self.tls not in ("on", "off", "required"): + raise ValueError("invalid TLS choice: '{}' (choose from 'on', 'off', 'required')".format(self.tls)) + if self.cmds: for cmd in self.cmds.strip(';').split(';'): if not cmd.startswith('/'): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/ui_cluster.py new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/ui_cluster.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/ui_cluster.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/ui_cluster.py 2021-03-19 05:13:08.000000000 +0100 @@ -243,17 +243,17 @@ qdevice_group.add_argument("--qnetd-hostname", dest="qnetd_addr", metavar="HOST", help="HOST or IP of the QNetd server to be used") qdevice_group.add_argument("--qdevice-port", dest="qdevice_port", metavar="PORT", type=int, default=5403, - help="TCP PORT of QNetd server(default:5403)") + help="TCP PORT of QNetd server (default:5403)") qdevice_group.add_argument("--qdevice-algo", dest="qdevice_algo", metavar="ALGORITHM", default="ffsplit", choices=['ffsplit', 'lms'], - help="QNetd decision ALGORITHM(ffsplit/lms, default:ffsplit)") + help="QNetd decision ALGORITHM (ffsplit/lms, default:ffsplit)") qdevice_group.add_argument("--qdevice-tie-breaker", dest="qdevice_tie_breaker", metavar="TIE_BREAKER", default="lowest", - help="QNetd TIE_BREAKER(lowest/highest/valid_node_id, default:lowest)") + help="QNetd TIE_BREAKER (lowest/highest/valid_node_id, default:lowest)") qdevice_group.add_argument("--qdevice-tls", dest="qdevice_tls", metavar="TLS", default="on", choices=['on', 'off', 'required'], - help="Whether using TLS on QDevice/QNetd(on/off/required, default:on)") + help="Whether using TLS on QDevice/QNetd (on/off/required, default:on)") qdevice_group.add_argument("--qdevice-heuristics", dest="qdevice_heuristics", metavar="COMMAND", - help="COMMAND to run with absolute path. For multiple commands, use \";\" to separate(details about heuristics can see man 8 corosync-qdevice)") + help="COMMAND to run with absolute path. For multiple commands, use \";\" to separate (details about heuristics can see man 8 corosync-qdevice)") qdevice_group.add_argument("--qdevice-heuristics-mode", dest="qdevice_heuristics_mode", metavar="MODE", choices=['on', 'sync', 'off'], - help="MODE of operation of heuristics(on/sync/off, default:sync)") + help="MODE of operation of heuristics (on/sync/off, default:sync)") storage_group = parser.add_argument_group("Storage configuration", "Options for configuring shared storage.") storage_group.add_argument("-p", "--partition-device", dest="shared_device", metavar="DEVICE", @@ -277,7 +277,7 @@ if options.qdevice_heuristics_mode and not options.qdevice_heuristics: parser.error("Option --qdevice-heuristics is required if want to configure heuristics mode") options.qdevice_heuristics_mode = options.qdevice_heuristics_mode or "sync" - elif re.search("--qdevice-.*", ' '.join(sys.argv)) or stage == "qdevice": + elif re.search("--qdevice-.*", ' '.join(sys.argv)) or (stage == "qdevice" and options.yes_to_all): parser.error("Option --qnetd-hostname is required if want to configure qdevice") if options.sbd_devices and options.diskless_sbd: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/ui_resource.py new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/ui_resource.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/crmsh/ui_resource.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/crmsh/ui_resource.py 2021-03-19 05:13:08.000000000 +0100 @@ -496,7 +496,8 @@ return m[:len(m)-3] if rsc not in compl.resources(): - context.fatal_error("Resource {} not exists in this cluster".format(rsc)) + context.warning("Resource {} not exists in this cluster".format(rsc)) + return valid_cmd_list = ["set", "delete", "show"] if cmd not in valid_cmd_list: context.fatal_error("{} is not valid command(should be one of {})".format(cmd, valid_cmd_list)) @@ -515,7 +516,7 @@ import re failcount_res = re.findall(r'fail-count-{}#(.*)_([0-9]+)'.format(rsc), out) if not failcount_res: - context.fatal_error("No failcount on node {} for resource {}".format(node, rsc)) + return True if value and int(value) == 0 else False failcount_dict = dict(failcount_res) # validate for operation and interval diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/setup.py new/crmsh-4.3.0+git.20210319.b0adc897/setup.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/setup.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/setup.py 2021-03-19 05:13:08.000000000 +0100 @@ -4,10 +4,10 @@ from setuptools import setup setup(name='crmsh', - version='4.2.0', + version='4.3.0', description='Command-line interface for High-Availability cluster management', - author='Kristoffer Gronlund', - author_email='kgronl...@suse.com', + author='Kristoffer Gronlund, Xin Liang', + author_email='xli...@suse.com', url='http://crmsh.github.io/', packages=['crmsh'], install_requires=['parallax', 'lxml', 'PyYAML', 'py-dateutil'], diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/test/features/qdevice_validate.feature new/crmsh-4.3.0+git.20210319.b0adc897/test/features/qdevice_validate.feature --- old/crmsh-4.3.0+git.20210311.c2e8856c/test/features/qdevice_validate.feature 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/test/features/qdevice_validate.feature 2021-03-19 05:13:08.000000000 +0100 @@ -102,7 +102,7 @@ Given Cluster service is "stopped" on "hanode1" When Run "crm cluster init -y" on "hanode1" Then Cluster service is "started" on "hanode1" - When Try "crm cluster init qdevice" + When Try "crm cluster init qdevice -y" Then Except multiple lines """ usage: init [options] [STAGE] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/test/features/resource_failcount.feature new/crmsh-4.3.0+git.20210319.b0adc897/test/features/resource_failcount.feature --- old/crmsh-4.3.0+git.20210311.c2e8856c/test/features/resource_failcount.feature 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/test/features/resource_failcount.feature 2021-03-19 05:13:08.000000000 +0100 @@ -12,14 +12,10 @@ @clean Scenario: Validation, input the wrong parameters - When Try "crm resource failcount ddd show hanode1" - Then Except "ERROR: resource.failcount: Resource ddd not exists in this cluster" When Try "crm resource failcount d showss hanode1" Then Except "ERROR: resource.failcount: showss is not valid command(should be one of ['set', 'delete', 'show'])" When Try "crm resource failcount d set hanode11 0" Then Except "ERROR: resource.failcount: Node hanode11 not in this cluster" - When Try "crm resource failcount d set hanode1 0" - Then Except "ERROR: resource.failcount: No failcount on node hanode1 for resource d" @clean Scenario: Set the failcount to 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/test/features/steps/const.py new/crmsh-4.3.0+git.20210319.b0adc897/test/features/steps/const.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/test/features/steps/const.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/test/features/steps/const.py 2021-03-19 05:13:08.000000000 +0100 @@ -98,20 +98,21 @@ --qnetd-hostname HOST HOST or IP of the QNetd server to be used - --qdevice-port PORT TCP PORT of QNetd server(default:5403) + --qdevice-port PORT TCP PORT of QNetd server (default:5403) --qdevice-algo ALGORITHM - QNetd decision ALGORITHM(ffsplit/lms, default:ffsplit) + QNetd decision ALGORITHM (ffsplit/lms, + default:ffsplit) --qdevice-tie-breaker TIE_BREAKER - QNetd TIE_BREAKER(lowest/highest/valid_node_id, + QNetd TIE_BREAKER (lowest/highest/valid_node_id, default:lowest) - --qdevice-tls TLS Whether using TLS on QDevice/QNetd(on/off/required, + --qdevice-tls TLS Whether using TLS on QDevice/QNetd (on/off/required, default:on) --qdevice-heuristics COMMAND COMMAND to run with absolute path. For multiple - commands, use ";" to separate(details about heuristics - can see man 8 corosync-qdevice) + commands, use ";" to separate (details about + heuristics can see man 8 corosync-qdevice) --qdevice-heuristics-mode MODE - MODE of operation of heuristics(on/sync/off, + MODE of operation of heuristics (on/sync/off, default:sync) Storage configuration: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.3.0+git.20210311.c2e8856c/test/unittests/test_bootstrap.py new/crmsh-4.3.0+git.20210319.b0adc897/test/unittests/test_bootstrap.py --- old/crmsh-4.3.0+git.20210311.c2e8856c/test/unittests/test_bootstrap.py 2021-03-11 08:39:55.000000000 +0100 +++ new/crmsh-4.3.0+git.20210319.b0adc897/test/unittests/test_bootstrap.py 2021-03-19 05:13:08.000000000 +0100 @@ -1416,6 +1416,51 @@ mock_status_done.assert_called_once_with() mock_start_qdevice.assert_called_once_with() + @mock.patch('crmsh.bootstrap.prompt_for_string') + def test_configure_qdevice_interactive_return(self, mock_prompt): + bootstrap._context = mock.Mock(yes_to_all=True) + bootstrap.configure_qdevice_interactive() + mock_prompt.assert_not_called() + + @mock.patch('crmsh.bootstrap.error') + @mock.patch('crmsh.bootstrap.prompt_for_string') + @mock.patch('crmsh.bootstrap.confirm') + def test_configure_qdevice_interactive_error(self, mock_confirm, mock_prompt, mock_error): + bootstrap._context = mock.Mock(yes_to_all=False) + mock_confirm.return_value = True + mock_prompt.return_value = None + mock_error.side_effect = SystemExit + + with self.assertRaises(SystemExit): + bootstrap.configure_qdevice_interactive() + + mock_error.assert_called_once_with("Address of QNetd is required") + mock_confirm.assert_called_once_with("Do you want to configure QDevice?") + mock_prompt.assert_called_once_with("HOST or IP of the QNetd server to be used") + + @mock.patch('crmsh.corosync.QDevice') + @mock.patch('crmsh.bootstrap.prompt_for_string') + @mock.patch('crmsh.bootstrap.confirm') + def test_configure_qdevice_interactive(self, mock_confirm, mock_prompt, mock_qdevice): + bootstrap._context = mock.Mock(yes_to_all=False) + mock_confirm.return_value = True + mock_prompt.side_effect = ["qnetd-node", 5403, "ffsplit", "lowest", "on", None] + mock_qdevice_inst = mock.Mock() + mock_qdevice.return_value = mock_qdevice_inst + + bootstrap.configure_qdevice_interactive() + mock_confirm.assert_called_once_with("Do you want to configure QDevice?") + mock_prompt.assert_has_calls([ + mock.call("HOST or IP of the QNetd server to be used"), + mock.call("TCP PORT of QNetd server", default=5403), + mock.call("QNetd decision ALGORITHM (ffsplit/lms)", default="ffsplit"), + mock.call("QNetd TIE_BREAKER (lowest/highest/valid node id)", default="lowest"), + mock.call("Whether using TLS on QDevice/QNetd (on/off/required)", default="on"), + mock.call("Heuristics COMMAND to run with absolute path; For multiple commands, use \";\" to separate") + ]) + mock_qdevice.assert_called_once_with('qnetd-node', port=5403, algo='ffsplit', tie_breaker='lowest', tls='on', cmds=None, mode=None) + mock_qdevice_inst.valid_attr.assert_called_once_with() + @mock.patch('crmsh.corosync.QDevice.start_qnetd') @mock.patch('crmsh.corosync.QDevice.enable_qnetd') @mock.patch('crmsh.utils.cluster_run_cmd')