Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2026-01-20 21:04:34 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new.1928 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Tue Jan 20 21:04:34 2026 rev:393 rq:1328202 version:5.0.0+20260120.522c67b3 Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2026-01-12 11:50:21.442229762 +0100 +++ /work/SRC/openSUSE:Factory/.crmsh.new.1928/crmsh.changes 2026-01-20 21:04:37.040212521 +0100 @@ -1,0 +2,15 @@ +Tue Jan 20 04:14:41 UTC 2026 - [email protected] + +- Update to version 5.0.0+20260120.522c67b3: + * Dev: unittests: Adjust unit test for previous commit + * Dev: behave: Adjust functional test for previous commit + * Dev: sbd: Replace "recommend" with "required" for log error message + * Dev: sbd: Check and fix stonith_enabled property + +------------------------------------------------------------------- +Wed Jan 14 07:11:48 UTC 2026 - [email protected] + +- Update to version 5.0.0+20260114.2a676131: + * Dev: options: Change 'force' option to be session-only (bsc#1254892) + +------------------------------------------------------------------- Old: ---- crmsh-5.0.0+20260112.268a7f4d.tar.bz2 New: ---- crmsh-5.0.0+20260120.522c67b3.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.RVmQrj/_old 2026-01-20 21:04:38.048253467 +0100 +++ /var/tmp/diff_new_pack.RVmQrj/_new 2026-01-20 21:04:38.052253629 +0100 @@ -41,7 +41,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0-or-later Group: %{pkg_group} -Version: 5.0.0+20260112.268a7f4d +Version: 5.0.0+20260120.522c67b3 Release: 0 URL: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.RVmQrj/_old 2026-01-20 21:04:38.104255742 +0100 +++ /var/tmp/diff_new_pack.RVmQrj/_new 2026-01-20 21:04:38.108255904 +0100 @@ -9,7 +9,7 @@ </service> <service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">f19f855883aa7c4dc6959b4afd70fbae83e7af8f</param> + <param name="changesrevision">522c67b3b78e1f84c3e55e70e2387d46dd4017b4</param> </service> </servicedata> (No newline at EOF) ++++++ crmsh-5.0.0+20260112.268a7f4d.tar.bz2 -> crmsh-5.0.0+20260120.522c67b3.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/bootstrap.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/bootstrap.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/bootstrap.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/bootstrap.py 2026-01-20 03:07:57.000000000 +0100 @@ -29,6 +29,8 @@ from string import Template from lxml import etree +import crmsh.options + from . import config, constants, ssh_key, sh, cibquery, user_of_host from . import utils from . import xmlutil @@ -251,7 +253,7 @@ if not with_sbd_option and self.yes_to_all: utils.fatal("Stage sbd should specify sbd device by -s or diskless sbd by -S option") - if ServiceManager().service_is_active(constants.SBD_SERVICE) and not config.core.force: + if ServiceManager().service_is_active(constants.SBD_SERVICE) and not crmsh.options.force: utils.fatal("Can't configure stage sbd: sbd.service already running! Please use crm option '-F' if need to redeploy") elif with_sbd_option: @@ -443,7 +445,7 @@ def confirm(msg): - if config.core.force or (_context and _context.yes_to_all): + if crmsh.options.force or (_context and _context.yes_to_all): return True disable_completion() rc = logger_utils.confirm(msg) @@ -2422,7 +2424,7 @@ """ global _context _context = context - force_flag = config.core.force or _context.force + force_flag = crmsh.options.force or _context.force init() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/cibconfig.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/cibconfig.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/cibconfig.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/cibconfig.py 2026-01-20 03:07:57.000000000 +0100 @@ -280,7 +280,7 @@ s = open(tmp).read() if hash(s) != filehash: ok = self.save(self._post_edit(s)) - if not ok and config.core.force: + if not ok and options.force: logger.error("Save failed and --force is set, aborting edit to avoid infinite loop") elif not ok and utils.ask("Edit or discard changes (yes to edit, no to discard)?"): continue @@ -3964,7 +3964,7 @@ # to remove doesn't exist. This should help scripted # workflows without compromising an interactive # use. - if not config.core.force: + if not options.force: logger_utils.no_object_err(obj_id) rc = False continue diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/config.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/config.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/config.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/config.py 2026-01-20 03:07:57.000000000 +0100 @@ -248,7 +248,6 @@ 'wait': opt_boolean('no'), 'add_quotes': opt_boolean('yes'), 'manage_children': opt_choice('ask', ('ask', 'never', 'always')), - 'force': opt_boolean('no'), 'debug': opt_boolean('no'), 'ptest': opt_program('', ('ptest', 'crm_simulate')), 'dotty': opt_program('', ('dotty',)), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/main.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/main.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/main.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/main.py 2026-01-20 03:07:57.000000000 +0100 @@ -313,7 +313,7 @@ options.profile = opts.profile or options.profile options.regression_tests = opts.regression_tests or options.regression_tests config.color.style = opts.display or config.color.style - config.core.force = opts.force or config.core.force + options.force = opts.force if opts.filename: logger_utils.reset_lineno() options.input_file, options.batch, options.interactive = opts.filename, True, False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/options.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/options.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/options.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/options.py 2026-01-20 03:07:57.000000000 +0100 @@ -16,3 +16,4 @@ scriptdir = "" # set to true when completing non-interactively shell_completion = False +force = False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/sbd.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/sbd.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/sbd.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/sbd.py 2026-01-20 03:07:57.000000000 +0100 @@ -558,6 +558,14 @@ ), ( + "stonith-enabled property", + self._check_stonith_enabled, + self._fix_stonith_enabled, + False, + [] + ), + + ( "unset SBD_DELAY_START in drop-in file", self._check_sbd_delay_start_unset_dropin, self._fix_sbd_delay_start_unset_dropin, @@ -665,11 +673,11 @@ self.sbd_watchdog_timeout_expected, self.sbd_msgwait_expected = SBDTimeout.get_sbd_metadata_expected() if self.sbd_watchdog_timeout < self.sbd_watchdog_timeout_expected: if not self.quiet: - logger.error("It's recommended that SBD watchdog timeout(now %d) >= %d", self.sbd_watchdog_timeout, self.sbd_watchdog_timeout_expected) + logger.error("It's required that SBD watchdog timeout(now %d) >= %d", self.sbd_watchdog_timeout, self.sbd_watchdog_timeout_expected) return CheckResult.ERROR if self.sbd_msgwait < self.sbd_msgwait_expected: if not self.quiet: - logger.error("It's recommended that SBD msgwait(now %d) >= %d", self.sbd_msgwait, self.sbd_msgwait_expected) + logger.error("It's required that SBD msgwait(now %d) >= %d", self.sbd_msgwait, self.sbd_msgwait_expected) return CheckResult.ERROR return CheckResult.SUCCESS @@ -690,7 +698,7 @@ self.sbd_watchdog_timeout_expected = SBDTimeout.get_sbd_watchdog_timeout_expected(diskless=True) if self.sbd_watchdog_timeout < self.sbd_watchdog_timeout_expected: if not self.quiet: - logger.error("It's recommended that SBD_WATCHDOG_TIMEOUT(now %d) >= %d", self.sbd_watchdog_timeout, self.sbd_watchdog_timeout_expected) + logger.error("It's required that SBD_WATCHDOG_TIMEOUT(now %d) >= %d", self.sbd_watchdog_timeout, self.sbd_watchdog_timeout_expected) return CheckResult.ERROR return CheckResult.SUCCESS @@ -705,7 +713,7 @@ elif config_value.isdigit() and expected_value.isdigit(): if int(config_value) < int(expected_value): if not self.quiet: - logger.error("It's recommended that SBD_DELAY_START is set to %s, now is %s", + logger.error("It's required that SBD_DELAY_START is set to %s, now is %s", expected_value, config_value) return CheckResult.ERROR else: @@ -715,7 +723,7 @@ return CheckResult.WARNING else: if not self.quiet: - logger.error("It's recommended that SBD_DELAY_START is set to %s, now is %s", + logger.error("It's required that SBD_DELAY_START is set to %s, now is %s", expected_value, config_value) return CheckResult.ERROR @@ -733,7 +741,7 @@ elif actual_start_timeout < expected_start_timeout: if not self.quiet: logger.error( - "It's recommended that systemd start timeout for sbd.service is set to %ds, now is %ds on node %s", + "It's required that systemd start timeout for sbd.service is set to %ds, now is %ds on node %s", expected_start_timeout, actual_start_timeout, node ) check_res_list.append(CheckResult.ERROR) @@ -766,12 +774,12 @@ else: if value == 0: if not self.quiet: - logger.error("It's recommended that stonith-watchdog-timeout is set to %d, now is not set", + logger.error("It's required that stonith-watchdog-timeout is set to %d, now is not set", self.stonith_watchdog_timeout) return CheckResult.ERROR if value < self.stonith_watchdog_timeout: if not self.quiet: - logger.error("It's recommended that stonith-watchdog-timeout is set to %d, now is %d", + logger.error("It's required that stonith-watchdog-timeout is set to %d, now is %d", self.stonith_watchdog_timeout, value) return CheckResult.ERROR elif value > self.stonith_watchdog_timeout: @@ -796,7 +804,7 @@ value = int(utils.crm_msec(value)/1000) if value < expected_value: if not self.quiet: - logger.error("It's recommended that stonith-timeout is set to %d, now is %d", + logger.error("It's required that stonith-timeout is set to %d, now is %d", expected_value, value) return CheckResult.ERROR elif value > expected_value: @@ -811,6 +819,18 @@ logger.info("Adjusting stonith-timeout to %d", expected_value) utils.set_property("stonith-timeout", expected_value) + def _check_stonith_enabled(self) -> CheckResult: + value = utils.get_property("stonith-enabled", get_default=False) + if utils.is_boolean_false(value): + if not self.quiet: + logger.error("It's required that stonith-enabled is set to true, now is false") + return CheckResult.ERROR + return CheckResult.SUCCESS + + def _fix_stonith_enabled(self): + logger.info("Setting stonith-enabled to true") + utils.set_property("stonith-enabled", "true") + def _check_sbd_delay_start_unset_dropin(self) -> CheckResult: if not SBDTimeout.is_sbd_delay_start(): return CheckResult.SUCCESS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_cib.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_cib.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_cib.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_cib.py 2026-01-20 03:07:57.000000000 +0100 @@ -69,7 +69,7 @@ new_cmd = "%s -e '%s'" % (self.extcmd, name) else: new_cmd = "%s -c '%s'" % (self.extcmd, name) - if constants.tmp_cib or config.core.force or "force" in opt_l or "--force" in opt_l: + if constants.tmp_cib or options.force or "force" in opt_l or "--force" in opt_l: new_cmd = "%s --force" % new_cmd if utils.ext_cmd(new_cmd) == 0: context.info("%s shadow CIB created" % name) @@ -213,7 +213,7 @@ # user made changes and now wants to switch to a # different and unequal CIB; we refuse to cooperate context.error_message("the requested CIB is different from the current one") - if config.core.force: + if options.force: context.info("CIB overwrite forced") elif not utils.ask("All changes will be dropped. Do you want to proceed?"): self._use(saved_cib, '') # revert to the previous CIB diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_cluster.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_cluster.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_cluster.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_cluster.py 2026-01-20 03:07:57.000000000 +0100 @@ -567,8 +567,8 @@ This command can remove the last node in the cluster, thus effectively removing the whole cluster. To remove -the last node, pass --force argument to crm or set -the config.core.force option.""", +the last node, pass --force argument to crm. +""", usage="remove [options] [<node> ...]", add_help=False, formatter_class=RawDescriptionHelpFormatter) parser.add_argument("-h", "--help", action="store_true", dest="help", help="Show this help message") parser.add_argument("-q", "--quiet", help="Be quiet (don't describe what's happening, just do it)", action="store_true", dest="quiet") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_configure.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_configure.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_configure.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_configure.py 2026-01-20 03:07:57.000000000 +0100 @@ -896,7 +896,7 @@ argl = list(args) arg_force = any((x in ('-f', '--force')) for x in argl) argl = [x for x in argl if x not in ('-f', '--force')] - if arg_force or config.core.force: + if arg_force or options.force: if self._stop_if_running(argl) > 0: utils.wait_dc_stable(what="Stopping %s" % (", ".join(argl))) cib_factory.ensure_cib_updated() @@ -963,7 +963,7 @@ if rc1 and bool(verify_result): return cib_factory.commit(replace=replace) - if force or config.core.force: + if force or options.force: logger.info("commit forced") return cib_factory.commit(force=True, replace=replace) if utils.ask("Do you still want to commit?"): @@ -989,10 +989,10 @@ @command.completers(compl.choice(['force'])) def do_upgrade(self, context, force=None): "usage: upgrade <force>" - if (not force or force != "force") and not config.core.force: + if (not force or force != "force") and not options.force: context.fatal_error("'force' option is required") cib_factory.ensure_cib_updated() - if cib_factory.upgrade_validate_with(force or config.core.force): + if cib_factory.upgrade_validate_with(force or options.force): logger.info("Current schema version is %s", cib_factory.get_schema(refresh=True)) return True return False diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_maintenance.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_maintenance.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_maintenance.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_maintenance.py 2026-01-20 03:07:57.000000000 +0100 @@ -3,10 +3,10 @@ from . import command from . import completers as compl -from . import config from . import cibconfig from . import utils from . import xmlutil +from . import options _compl_actions = compl.choice(['start', 'stop', 'monitor', 'meta-data', 'validate-all', 'promote', 'demote', 'notify', 'reload', 'migrate_from', @@ -75,7 +75,7 @@ context.fatal_error("Resource not found: %s" % (resource)) if not xmlutil.is_resource(obj.node): context.fatal_error("Not a resource: %s" % (resource)) - if not config.core.force and not self._in_maintenance_mode(obj): + if not options.force and not self._in_maintenance_mode(obj): context.fatal_error("Not in maintenance mode.") if ssh is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_node.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_node.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_node.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_node.py 2026-01-20 03:07:57.000000000 +0100 @@ -2,7 +2,6 @@ # Copyright (C) 2013 Kristoffer Gronlund <[email protected]> # See COPYING for license information. import os -import re import copy import subprocess from lxml import etree @@ -18,6 +17,7 @@ from .cliformat import cli_nvpairs, nvpairs2list from . import term from . import cibconfig +from . import options from .sh import ShellUtils from . import log @@ -443,7 +443,7 @@ if not utils.has_stonith_running(): logger.error("fence command requires stonith device configured and running") return False - if not config.core.force and \ + if not options.force and \ not utils.ask("Fencing %s will shut down the node and migrate any resources that are running on it! Do you want to fence %s?" % (node, node)): return False if xmlutil.is_remote_node(node): @@ -459,7 +459,7 @@ node = utils.this_node() if not utils.is_name_sane(node): return False - if not config.core.force and \ + if not options.force and \ not utils.ask("Do you really want to drop state for node %s?" % node): return False @@ -493,7 +493,7 @@ rc = False cmd = "%s --force -R %s" % (cls.crm_node, node) if not rc: - if config.core.force: + if options.force: logger.info('proceeding with node %s removal', node) else: return False @@ -515,7 +515,7 @@ def do_delete(self, context, node): 'usage: delete <node>' logger.warning('`crm node delete` is deprecated and will very likely be dropped in the near future. It is auto-replaced as `crm cluster remove -c {}`.'.format(node)) - if config.core.force: + if options.force: args = ['crm', 'cluster', 'remove', '-F', '-c', node] else: args = ['crm', 'cluster', 'remove', '-c', node] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_options.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_options.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_options.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_options.py 2026-01-20 03:07:57.000000000 +0100 @@ -20,7 +20,6 @@ 'wait': ('core', 'wait'), 'add_quotes': ('core', 'add_quotes'), 'manage_children': ('core', 'manage_children'), - 'force': ('core', 'force'), 'debug': ('core', 'debug'), 'ptest': ('core', 'ptest'), 'dotty': ('core', 'dotty'), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_resource.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_resource.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_resource.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_resource.py 2026-01-20 03:07:57.000000000 +0100 @@ -401,7 +401,7 @@ lifetime = None argl = list(args) - force = "force" in utils.fetch_opts(argl, ["force"]) or config.core.force + force = "force" in utils.fetch_opts(argl, ["force"]) or options.force if len(argl) >= 3: context.fatal_error(usage) if len(argl) == 2: # must be <node> <lifetime> @@ -423,7 +423,7 @@ opts = "--node '%s'" % node if lifetime: opts = "%s --lifetime '%s'" % (opts, lifetime) - if force or config.core.force: + if force or options.force: opts = "%s --force" % opts rc = utils.ext_cmd(action_cmd % (rsc, opts)) if rc == 0: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_site.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_site.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_site.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_site.py 2026-01-20 03:07:57.000000000 +0100 @@ -5,9 +5,9 @@ import time from . import command from . import completers as compl -from . import config from . import utils from . import log +from . import options logger = log.setup_logger(__name__) @@ -60,7 +60,7 @@ "usage: ticket {grant|revoke|standby|activate|show|time|delete} <ticket>" base_cmd = "crm_ticket" - if config.core.force: + if options.force: base_cmd += " --force" attr_cmd = _ticket_commands.get(subcmd) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_template.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_template.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/ui_template.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/ui_template.py 2026-01-20 03:07:57.000000000 +0100 @@ -102,9 +102,8 @@ if not self.config_exists(name): return False if name == self.curr_conf: - if not force and not config.core.force and \ - not utils.ask("Do you really want to remove config %s which is in use?" % - self.curr_conf): + if not force and not options.force and \ + not utils.ask("Config %s is currently in use. Do you really want to delete it?" % name): return False else: self.curr_conf = '' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/crmsh/utils.py new/crmsh-5.0.0+20260120.522c67b3/crmsh/utils.py --- old/crmsh-5.0.0+20260112.268a7f4d/crmsh/utils.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/crmsh/utils.py 2026-01-20 03:07:57.000000000 +0100 @@ -267,10 +267,10 @@ block until the process is brought to foreground. Global Options: - * core.force: always return true without asking + * options.force: always return true without asking * options.ask_no: do not ask and return false """ - if config.core.force: + if options.force: logger.info("%s [YES]", msg) return True if not can_ask(background_wait): @@ -2895,7 +2895,7 @@ logger.info("Cluster is already in maintenance mode") yield True return - if not config.core.force: + if not options.force: yield False return diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/doc/crm.8.adoc new/crmsh-5.0.0+20260120.522c67b3/doc/crm.8.adoc --- old/crmsh-5.0.0+20260112.268a7f4d/doc/crm.8.adoc 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/doc/crm.8.adoc 2026-01-20 03:07:57.000000000 +0100 @@ -3111,7 +3111,7 @@ related constraints are removed as well. If the object is a started resource, it will not be deleted unless the -+--force+ flag is passed to the command, or the +force+ option is set. ++--force+ flag is passed to the command. Usage: ............... diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/etc/crm.conf.in new/crmsh-5.0.0+20260120.522c67b3/etc/crm.conf.in --- old/crmsh-5.0.0+20260112.268a7f4d/etc/crm.conf.in 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/etc/crm.conf.in 2026-01-20 03:07:57.000000000 +0100 @@ -12,7 +12,6 @@ ; wait = no ; add_quotes = yes ; manage_children = ask -; force = no ; debug = no ; ptest = ptest, crm_simulate ; dotty = dotty diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/test/features/bootstrap_sbd_delay.feature new/crmsh-5.0.0+20260120.522c67b3/test/features/bootstrap_sbd_delay.feature --- old/crmsh-5.0.0+20260112.268a7f4d/test/features/bootstrap_sbd_delay.feature 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/test/features/bootstrap_sbd_delay.feature 2026-01-20 03:07:57.000000000 +0100 @@ -341,26 +341,26 @@ # check sbd disk metadata When Run "sbd -1 15 -4 16 -d /dev/sda1 create" on "hanode1" When Try "crm sbd configur show disk_metadata" on "hanode1" - Then Expected "ERROR: It's recommended that SBD msgwait(now 16) >= 30" in stderr + Then Expected "ERROR: It's required that SBD msgwait(now 16) >= 30" in stderr When Try "crm cluster health sbd" on "hanode1" - Then Expected "ERROR: It's recommended that SBD msgwait(now 16) >= 30" in stderr + Then Expected "ERROR: It's required that SBD msgwait(now 16) >= 30" in stderr When Run "crm cluster health sbd --fix" on "hanode1" Then Expected "SBD: Check sbd timeout configuration: OK" in stdout # check SBD_DELAY_START When Run "sed -i 's/SBD_DELAY_START=.*/SBD_DELAY_START=40/' /etc/sysconfig/sbd" on "hanode1" When Run "sed -i 's/SBD_DELAY_START=.*/SBD_DELAY_START=40/' /etc/sysconfig/sbd" on "hanode2" When Try "crm sbd configure show" on "hanode1" - Then Expected "It's recommended that SBD_DELAY_START is set to 71, now is 40" in stderr + Then Expected "It's required that SBD_DELAY_START is set to 71, now is 40" in stderr When Try "crm cluster health sbd" on "hanode1" - Then Expected "It's recommended that SBD_DELAY_START is set to 71, now is 40" in stderr + Then Expected "It's required that SBD_DELAY_START is set to 71, now is 40" in stderr When Run "crm cluster health sbd --fix" on "hanode1" Then Expected "SBD: Check sbd timeout configuration: OK" in stdout # check stonith-timeout When Run "crm configure property stonith-timeout=50" on "hanode1" When Try "crm sbd configure show" on "hanode1" - Then Expected "It's recommended that stonith-timeout is set to 71, now is 50" in stderr + Then Expected "It's required that stonith-timeout is set to 71, now is 50" in stderr When Try "crm cluster health sbd" on "hanode1" - Then Expected "It's recommended that stonith-timeout is set to 71, now is 50" in stderr + Then Expected "It's required that stonith-timeout is set to 71, now is 50" in stderr When Run "crm cluster health sbd --fix" on "hanode1" Then Expected "SBD: Check sbd timeout configuration: OK" in stdout # Adjust token timeout in corosync.conf @@ -368,9 +368,9 @@ When Run "sed -i 's/token: .*/token: 10000/' /etc/corosync/corosync.conf" on "hanode2" When Run "corosync-cfgtool -R" on "hanode1" When Try "crm sbd configure show" on "hanode1" - Then Expected "It's recommended that SBD_DELAY_START is set to 82, now is 71" in stderr + Then Expected "It's required that SBD_DELAY_START is set to 82, now is 71" in stderr When Try "crm cluster health sbd" on "hanode1" - Then Expected "It's recommended that SBD_DELAY_START is set to 82, now is 71" in stderr + Then Expected "It's required that SBD_DELAY_START is set to 82, now is 71" in stderr When Run "crm cluster health sbd --fix" on "hanode1" Then Expected "SBD: Check sbd timeout configuration: OK" in stdout @@ -388,8 +388,8 @@ # Delete stonith-watchdog-timeout When Delete property "stonith-watchdog-timeout" from cluster When Try "crm sbd configure show" on "hanode1" - Then Expected "It's recommended that stonith-watchdog-timeout is set to 30, now is not set" in stderr + Then Expected "It's required that stonith-watchdog-timeout is set to 30, now is not set" in stderr When Try "crm cluster health sbd" on "hanode1" - Then Expected "It's recommended that stonith-watchdog-timeout is set to 30, now is not set" in stderr + Then Expected "It's required that stonith-watchdog-timeout is set to 30, now is not set" in stderr When Run "crm cluster health sbd --fix" on "hanode1" Then Expected "SBD: Check sbd timeout configuration: OK" in stdout diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/test/features/steps/const.py new/crmsh-5.0.0+20260120.522c67b3/test/features/steps/const.py --- old/crmsh-5.0.0+20260112.268a7f4d/test/features/steps/const.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/test/features/steps/const.py 2026-01-20 03:07:57.000000000 +0100 @@ -272,8 +272,7 @@ This command can remove the last node in the cluster, thus effectively removing the whole cluster. To remove -the last node, pass --force argument to crm or set -the config.core.force option. +the last node, pass --force argument to crm. options: -h, --help Show this help message diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/test/unittests/test_sbd.py new/crmsh-5.0.0+20260120.522c67b3/test/unittests/test_sbd.py --- old/crmsh-5.0.0+20260112.268a7f4d/test/unittests/test_sbd.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/test/unittests/test_sbd.py 2026-01-20 03:07:57.000000000 +0100 @@ -388,6 +388,7 @@ self.instance_fix._check_stonith_watchdog_timeout = Mock(return_value=sbd.CheckResult.SUCCESS) self.instance_fix._check_stonith_timeout = Mock(return_value=sbd.CheckResult.SUCCESS) self.instance_fix._check_sbd_delay_start_unset_dropin = Mock(return_value=sbd.CheckResult.SUCCESS) + self.instance_fix._check_stonith_enabled = Mock(return_value=sbd.CheckResult.SUCCESS) res = self.instance_fix.check_and_fix() self.assertEqual(res, sbd.CheckResult.SUCCESS) @@ -434,7 +435,7 @@ mock_get_sbd_metadata_expected.return_value = (15, 30) self.instance_check.sbd_watchdog_timeout = 10 self.assertEqual(self.instance_check._check_sbd_disk_metadata(), sbd.CheckResult.ERROR) - mock_logger_error.assert_called_once_with("It's recommended that SBD watchdog timeout(now %d) >= %d", 10, 15) + mock_logger_error.assert_called_once_with("It's required that SBD watchdog timeout(now %d) >= %d", 10, 15) @patch('logging.Logger.error') @patch('crmsh.sbd.SBDTimeout.get_sbd_metadata_expected') @@ -444,7 +445,7 @@ self.instance_check.sbd_watchdog_timeout = 10 self.instance_check.sbd_msgwait = 20 self.assertEqual(self.instance_check._check_sbd_disk_metadata(), sbd.CheckResult.ERROR) - mock_logger_error.assert_called_once_with("It's recommended that SBD msgwait(now %d) >= %d", 20, 25) + mock_logger_error.assert_called_once_with("It's required that SBD msgwait(now %d) >= %d", 20, 25) @patch('crmsh.sbd.SBDTimeout.get_sbd_metadata_expected') def test_check_sbd_disk_metadata_success(self, mock_get_sbd_metadata_expected): @@ -472,7 +473,7 @@ mock_get_sbd_watchdog_timeout_expected.return_value = 10 self.instance_check.sbd_watchdog_timeout = 3 self.assertEqual(self.instance_check._check_sbd_watchdog_timeout(), sbd.CheckResult.ERROR) - mock_logger_error.assert_called_once_with("It's recommended that SBD_WATCHDOG_TIMEOUT(now %d) >= %d", 3, 10) + mock_logger_error.assert_called_once_with("It's required that SBD_WATCHDOG_TIMEOUT(now %d) >= %d", 3, 10) @patch('crmsh.sbd.SBDTimeout.get_sbd_watchdog_timeout_expected') def test_check_sbd_watchdog_timeout_success(self, mock_get_sbd_watchdog_timeout_expected): @@ -492,7 +493,7 @@ self.instance_check.sbd_delay_start_value_expected = "100" self.instance_check.sbd_delay_start_value_from_config = "30" self.assertEqual(self.instance_check._check_sbd_delay_start(), sbd.CheckResult.ERROR) - mock_logger_error.assert_called_once_with("It's recommended that SBD_DELAY_START is set to %s, now is %s", "100", "30") + mock_logger_error.assert_called_once_with("It's required that SBD_DELAY_START is set to %s, now is %s", "100", "30") def test_check_sbd_delay_start_success(self): self.instance_check.sbd_delay_start_value_expected = "50" @@ -528,7 +529,7 @@ self.assertEqual(self.instance_check._check_sbd_systemd_start_timeout(), sbd.CheckResult.ERROR) mock_logger_warning.assert_called_once_with("It's recommended that systemd start timeout for sbd.service is set to %ds, now is %ds on node %s", 60, 70, 'node3') - mock_logger_error.assert_called_once_with("It's recommended that systemd start timeout for sbd.service is set to %ds, now is %ds on node %s", 60, 50, 'node2') + mock_logger_error.assert_called_once_with("It's required that systemd start timeout for sbd.service is set to %ds, now is %ds on node %s", 60, 50, 'node2') @patch('crmsh.utils.cluster_run_cmd') @patch('crmsh.bootstrap.sync_path') @@ -557,7 +558,7 @@ self.instance_check.stonith_watchdog_timeout = 15 mock_get_property.return_value = "" self.assertEqual(self.instance_check._check_stonith_watchdog_timeout(), sbd.CheckResult.ERROR) - mock_logger_error.assert_called_once_with("It's recommended that stonith-watchdog-timeout is set to %d, now is not set", 15) + mock_logger_error.assert_called_once_with("It's required that stonith-watchdog-timeout is set to %d, now is not set", 15) @patch('crmsh.utils.get_property') def test_check_stonith_watchdog_timeout_success(self, mock_get_property): @@ -589,7 +590,7 @@ self.instance_check.get_stonith_timeout_expected = Mock(return_value=60) mock_get_property.return_value = 30 self.assertEqual(self.instance_check._check_stonith_timeout(), sbd.CheckResult.ERROR) - mock_logger_error.assert_called_once_with("It's recommended that stonith-timeout is set to %d, now is %d", 60, 30) + mock_logger_error.assert_called_once_with("It's required that stonith-timeout is set to %d, now is %d", 60, 30) @patch('logging.Logger.warning') @patch('crmsh.utils.get_property') @@ -779,6 +780,29 @@ self.instance_fix._fix_fence_sbd() mock_logger_info.assert_called_once_with("Starting fence agent %s", 'fence_sbd_0') + @patch('crmsh.utils.is_boolean_false') + @patch('crmsh.utils.get_property') + def test_check_stonith_enabled_success(self, mock_get_property, mock_is_boolean_false): + mock_get_property.return_value = "true" + mock_is_boolean_false.return_value = False + self.assertEqual(self.instance_check._check_stonith_enabled(), sbd.CheckResult.SUCCESS) + + @patch('logging.Logger.error') + @patch('crmsh.utils.is_boolean_false') + @patch('crmsh.utils.get_property') + def test_check_stonith_enabled_failure(self, mock_get_property, mock_is_boolean_false, mock_logger_error): + mock_get_property.return_value = "false" + mock_is_boolean_false.return_value = True + self.assertEqual(self.instance_check._check_stonith_enabled(), sbd.CheckResult.ERROR) + mock_logger_error.assert_called_once_with("It's required that stonith-enabled is set to true, now is false") + + @patch('logging.Logger.info') + @patch('crmsh.utils.set_property') + def test_fix_stonith_enabled(self, mock_set_property, mock_logger_info): + self.instance_fix._fix_stonith_enabled() + mock_logger_info.assert_called_once_with("Setting stonith-enabled to true") + mock_set_property.assert_called_once_with('stonith-enabled', 'true') + class TestSBDManager(unittest.TestCase): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-5.0.0+20260112.268a7f4d/test/unittests/test_utils.py new/crmsh-5.0.0+20260120.522c67b3/test/unittests/test_utils.py --- old/crmsh-5.0.0+20260112.268a7f4d/test/unittests/test_utils.py 2026-01-12 08:12:35.000000000 +0100 +++ new/crmsh-5.0.0+20260120.522c67b3/test/unittests/test_utils.py 2026-01-20 03:07:57.000000000 +0100 @@ -13,7 +13,7 @@ from itertools import chain import crmsh.utils -from crmsh import utils, config, tmpfiles, constants, parallax +from crmsh import utils, config, tmpfiles, constants, options logging.basicConfig(level=logging.DEBUG) @@ -1357,7 +1357,7 @@ @mock.patch('logging.Logger.warning') @mock.patch('crmsh.utils.is_dc_idle') def test_leverage_maintenance_mode_skip(mock_idle, mock_warn): - config.core.force = True + options.force = True mock_idle.return_value = False with utils.leverage_maintenance_mode() as result: assert result is False @@ -1369,7 +1369,7 @@ @mock.patch('logging.Logger.info') @mock.patch('crmsh.utils.is_dc_idle') def test_leverage_maintenance_mode(mock_idle, mock_info, mock_set, mock_delete): - config.core.force = True + options.force = True mock_idle.return_value = True with utils.leverage_maintenance_mode() as result: assert result is True
