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

Reply via email to