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-02-26 18:59:40
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/crmsh (Old)
 and      /work/SRC/openSUSE:Factory/.crmsh.new.29461 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "crmsh"

Thu Feb 26 18:59:40 2026 rev:397 rq:1335252 version:5.0.0+20260226.8b99a4c5

Changes:
--------
--- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes      2026-02-09 
13:53:01.680010573 +0100
+++ /work/SRC/openSUSE:Factory/.crmsh.new.29461/crmsh.changes   2026-02-26 
18:59:43.649240492 +0100
@@ -1,0 +2,33 @@
+Thu Feb 26 10:07:15 UTC 2026 - [email protected]
+
+- Update to version 5.0.0+20260226.8b99a4c5:
+  * Chore: codecov: update expected report count
+  * Fix: behave: Remove redundant dos2unix in run-functional-tests (#2034)
+  * Dev: behave: Adjust functional test for previous commit
+  * Dev: bootstrap: Disable sbd.service when the process is in 'cluster' stage
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: sbd: Move diskless SBD warning to adjust_properties
+  * Dev: sbd: record ERROR when prerequisite checks fail
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: sbd: rename SBDTimeoutChecker to SBDConfigChecker
+  * Dev: sbd: Replace magic numbers with IntEnum for check prerequisites
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: sbd: Add self._log_when_not_quiet() method to avoid checking 
self.quiet everywhere
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: bootstrap: The sbd stage now requires a running cluster
+  * Dev: sbd: Adjust related properties after cluster started on init process
+  * Dev: sbd: Add quiet attribute to class SBDTimeout
+
+-------------------------------------------------------------------
+Tue Feb 10 04:53:16 UTC 2026 - [email protected]
+
+- Update to version 5.0.0+20260210.baf54ddb:
+  * Dev: workflows: Enable Python 3.14 for unit test
+
+-------------------------------------------------------------------
+Tue Feb 10 03:12:21 UTC 2026 - [email protected]
+
+- Update to version 5.0.0+20260210.24e46036:
+  * minieval.py : remove ast.Num and ast.Str no longer available in Python 3.14
+
+-------------------------------------------------------------------

Old:
----
  crmsh-5.0.0+20260209.ed56b53c.tar.bz2

New:
----
  crmsh-5.0.0+20260226.8b99a4c5.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.wCq83j/_old  2026-02-26 18:59:45.261307755 +0100
+++ /var/tmp/diff_new_pack.wCq83j/_new  2026-02-26 18:59:45.265307922 +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+20260209.ed56b53c
+Version:        5.0.0+20260226.8b99a4c5
 Release:        0
 URL:            http://crmsh.github.io
 Source0:        %{name}-%{version}.tar.bz2

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.wCq83j/_old  2026-02-26 18:59:45.321310259 +0100
+++ /var/tmp/diff_new_pack.wCq83j/_new  2026-02-26 18:59:45.325310426 +0100
@@ -9,7 +9,7 @@
 </service>
 <service name="tar_scm">
   <param name="url">https://github.com/ClusterLabs/crmsh.git</param>
-  <param 
name="changesrevision">41e6d81ca2affd5395ba48265e00ab71c111b1d8</param>
+  <param 
name="changesrevision">c57573d04cc8f9f0a4162d330529bc609b721c2d</param>
 </service>
 </servicedata>
 (No newline at EOF)

++++++ crmsh-5.0.0+20260209.ed56b53c.tar.bz2 -> 
crmsh-5.0.0+20260226.8b99a4c5.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/.github/workflows/crmsh-ci.yml 
new/crmsh-5.0.0+20260226.8b99a4c5/.github/workflows/crmsh-ci.yml
--- old/crmsh-5.0.0+20260209.ed56b53c/.github/workflows/crmsh-ci.yml    
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/.github/workflows/crmsh-ci.yml    
2026-02-26 10:31:40.000000000 +0100
@@ -35,7 +35,7 @@
     runs-on: ubuntu-24.04
     strategy:
       matrix:
-        python-version: ['3.11', '3.12', '3.13']
+        python-version: ['3.11', '3.12', '3.13', '3.14']
       fail-fast: false
     timeout-minutes: 5
     steps:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260209.ed56b53c/codecov.yml 
new/crmsh-5.0.0+20260226.8b99a4c5/codecov.yml
--- old/crmsh-5.0.0+20260209.ed56b53c/codecov.yml       2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/codecov.yml       2026-02-26 
10:31:40.000000000 +0100
@@ -8,7 +8,7 @@
         threshold: 0.35%
 codecov:
   notify:
-    after_n_builds: 33
+    after_n_builds: 34
 comment:
-  after_n_builds: 33
+  after_n_builds: 34
   layout: "condensed_header, flags, files, condensed_footer"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260209.ed56b53c/crmsh/bootstrap.py 
new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/bootstrap.py
--- old/crmsh-5.0.0+20260209.ed56b53c/crmsh/bootstrap.py        2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/bootstrap.py        2026-02-26 
10:31:40.000000000 +0100
@@ -304,7 +304,7 @@
         if self.type == "init":
             if self.stage not in INIT_STAGES_ALL:
                 utils.fatal(f"Invalid stage: {self.stage}(available stages: 
{', '.join(INIT_STAGES_EXTERNAL)})")
-            if self.stage in ("admin", "qdevice", "ocfs2") and not 
self.cluster_is_running:
+            if self.stage in ("admin", "sbd", "qdevice", "ocfs2") and not 
self.cluster_is_running:
                 utils.fatal(f"Cluster is inactive, can't run '{self.stage}' 
stage")
             if self.stage in ("corosync", "cluster") and 
self.cluster_is_running:
                 utils.fatal(f"Cluster is active, can't run '{self.stage}' 
stage")
@@ -1465,6 +1465,11 @@
     """
     Initial cluster configuration.
     """
+    if _context.stage == "cluster":
+        service_manager = ServiceManager()
+        if service_manager.service_is_enabled(constants.SBD_SERVICE):
+            service_manager.disable_service(constants.SBD_SERVICE)
+
     generate_pacemaker_remote_auth()
 
     init_cluster_local()
@@ -1483,9 +1488,7 @@
 rsc_defaults rsc-options: resource-stickiness=1 migration-threshold=3
 """)
 
-    if ServiceManager().service_is_enabled(constants.SBD_SERVICE):
-        _context.sbd_manager.configure_sbd()
-
+    adjust_properties()
 
 
 def init_admin():
@@ -2173,10 +2176,10 @@
     corosync.configure_two_node(removing=True)
     logger.info("Propagating configuration changes across the remaining nodes")
     sync_path(corosync.conf())
-    adjust_properties()
-
     sh.cluster_shell().get_stdout_or_raise_error("corosync-cfgtool -R")
 
+    adjust_properties()
+
     if not dead_node:
         FirewallManager(peer=node).remove_service()
 
@@ -2204,7 +2207,6 @@
         "ssh": ssh_stage_finished,
         "firewalld": FirewallManager.firewalld_stage_finished,
         "corosync": corosync_stage_finished,
-        "sbd": lambda: True,
         "cluster": is_online
 }
 
@@ -2762,7 +2764,7 @@
     Adjust stonith-timeout for sbd and other scenarios
     """
     if ServiceManager().service_is_active(constants.SBD_SERVICE):
-        sbd.SBDTimeoutChecker(quiet=True, fix=True).check_and_fix()
+        sbd.SBDConfigChecker(quiet=True, fix=True).check_and_fix()
     else:
         value = get_stonith_timeout_generally_expected()
         if value:
@@ -2790,6 +2792,7 @@
     adjust_stonith_timeout()
     adjust_priority_in_rsc_defaults(is_2node_wo_qdevice)
     adjust_priority_fencing_delay(is_2node_wo_qdevice)
+    sbd.SBDManager.warn_diskless_sbd()
 
 
 def retrieve_files(from_node: str, file_list: list, msg: str = None):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260209.ed56b53c/crmsh/minieval.py 
new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/minieval.py
--- old/crmsh-5.0.0+20260209.ed56b53c/crmsh/minieval.py 2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/minieval.py 2026-02-26 
10:31:40.000000000 +0100
@@ -183,8 +183,7 @@
         self.names = names
 
         self.nodes = {
-            ast.Num: self._eval_num,
-            ast.Str: self._eval_str,
+            ast.Constant: self._eval_constant,
             ast.Name: self._eval_name,
             ast.UnaryOp: self._eval_unaryop,
             ast.BinOp: self._eval_binop,
@@ -204,9 +203,13 @@
         elif isinstance(self.names, dict) and "None" not in self.names:
             self.names["None"] = None
 
-        # py3.8 uses ast.Constant instead of ast.Num, ast.Str, ast.NameConstant
-        if hasattr(ast, 'Constant'):
-            self.nodes[ast.Constant] = self._eval_constant
+        # py3.14 completely dropped ast.Num and ast.Str
+        # in favor of ast.Constant that encodes different types of value
+        # See https://docs.python.org/3/whatsnew/3.14.html#id9
+        if hasattr(ast, 'Str'):
+            self.nodes[ast.Str] = self._eval_str
+        if hasattr(ast, 'Num'):
+            self.nodes[ast.Num] = self._eval_num
 
     def evaluate(self, expr):
         """ evaluate an expresssion, using the operators, functions and
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260209.ed56b53c/crmsh/sbd.py 
new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/sbd.py
--- old/crmsh-5.0.0+20260209.ed56b53c/crmsh/sbd.py      2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/sbd.py      2026-02-26 
10:31:40.000000000 +0100
@@ -3,7 +3,8 @@
 import typing
 import shutil
 import time
-from enum import Enum
+import logging
+from enum import Enum, IntEnum, auto
 from . import utils, sh
 from . import bootstrap
 from . import log
@@ -212,9 +213,15 @@
         self.crashdump_watchdog_timeout = None
         self.sbd_msgwait_expected = None
         self.sbd_watchdog_timeout_expected = None
+        self.quiet = False
         if self.context:
+            self.quiet = self.context.quiet
             self._initialize_timeout_from_bootstrap()
 
+    def _log_when_not_quiet(self, level, message, *args, **kwargs):
+        if not self.quiet:
+            logger.log(level, message, *args, **kwargs)
+
     def _initialize_timeout_from_bootstrap(self):
         self._set_sbd_watchdog_timeout()
         if self.context.diskless_sbd:
@@ -230,7 +237,11 @@
         if "sbd.watchdog_timeout" in self.context.profiles_dict:
             self.sbd_watchdog_timeout = 
int(self.context.profiles_dict["sbd.watchdog_timeout"])
         if self.context.is_s390 and self.sbd_watchdog_timeout < 
self.SBD_WATCHDOG_TIMEOUT_DEFAULT_S390:
-            logger.warning("sbd_watchdog_timeout is set to %d for s390, it was 
%d", self.SBD_WATCHDOG_TIMEOUT_DEFAULT_S390, self.sbd_watchdog_timeout)
+            self._log_when_not_quiet(
+                logging.WARNING,
+                "sbd watchdog_timeout is set to %d for s390, it was %d",
+                self.SBD_WATCHDOG_TIMEOUT_DEFAULT_S390, 
self.sbd_watchdog_timeout
+            )
             self.sbd_watchdog_timeout = self.SBD_WATCHDOG_TIMEOUT_DEFAULT_S390
 
     def _set_sbd_msgwait(self):
@@ -243,7 +254,11 @@
         if "sbd.msgwait" in self.context.profiles_dict:
             sbd_msgwait = int(self.context.profiles_dict["sbd.msgwait"])
             if sbd_msgwait < sbd_msgwait_default:
-                logger.warning("sbd msgwait is set to %d, it was %d", 
sbd_msgwait_default, sbd_msgwait)
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "sbd msgwait is set to %d, it was %d",
+                    sbd_msgwait_default, sbd_msgwait
+                )
                 sbd_msgwait = sbd_msgwait_default
         self.sbd_msgwait = sbd_msgwait
 
@@ -256,7 +271,8 @@
             qdevice_sync_timeout = utils.get_qdevice_sync_timeout()
             if self.sbd_watchdog_timeout <= qdevice_sync_timeout:
                 watchdog_timeout_with_qdevice = qdevice_sync_timeout + 
self.QDEVICE_SYNC_TIMEOUT_MARGIN
-                logger.warning(
+                self._log_when_not_quiet(
+                    logging.WARNING,
                     "SBD_WATCHDOG_TIMEOUT should not less than %d for qdevice, 
it was %d",
                     watchdog_timeout_with_qdevice, self.sbd_watchdog_timeout
                 )
@@ -264,7 +280,8 @@
         # add sbd and qdevice together from beginning
         elif self.context.qdevice_inst:
             if self.sbd_watchdog_timeout < 
self.SBD_WATCHDOG_TIMEOUT_DEFAULT_WITH_QDEVICE:
-                logger.warning(
+                self._log_when_not_quiet(
+                    logging.WARNING,
                     "SBD_WATCHDOG_TIMEOUT should not less than %d for qdevice, 
it was %d",
                     self.SBD_WATCHDOG_TIMEOUT_DEFAULT_WITH_QDEVICE, 
self.sbd_watchdog_timeout
                 )
@@ -458,7 +475,21 @@
     __str__ = lambda self: self.name
 
 
-class SBDTimeoutChecker(SBDTimeout):
+class SBDCheckItem(IntEnum):
+    SBD_DISK_METADATA = 0
+    SBD_DEVICE_METADATA_CONSISTENCY = auto()
+    SBD_WATCHDOG_TIMEOUT = auto()
+    FENCE_SBD_AGENT = auto()
+    SBD_DELAY_START = auto()
+    SBD_SYSTEMD_START_TIMEOUT = auto()
+    STONITH_WATCHDOG_TIMEOUT_PROPERTY = auto()
+    STONITH_TIMEOUT_PROPERTY = auto()
+    STONITH_ENABLED_PROPERTY = auto()
+    UNSET_SBD_DELAY_START_IN_DROPIN = auto()
+    ENABLE_SBD_SERVICE = auto()
+
+
+class SBDConfigChecker(SBDTimeout):
 
     def __init__(self, quiet=False, fix=False):
         super().__init__()
@@ -492,8 +523,8 @@
             logger.info('SBD: Check sbd timeout configuration: OK.')
             return True
 
-    def check_and_fix(self) -> CheckResult:
-        checks_and_fixes = [
+    def _check_and_fix_items(self) -> list[tuple]:
+        return  [
             # issue name, check method, fix method, SSH required, 
prerequisites checks
             (
                 "SBD disk metadata",
@@ -508,7 +539,7 @@
                 self._check_sbd_device_metadata_consistency,
                 self._fix_sbd_device_metadata_consistency,
                 True,
-                [0]
+                [SBDCheckItem.SBD_DISK_METADATA]
             ),
 
             (
@@ -532,7 +563,11 @@
                 self._check_sbd_delay_start,
                 self._fix_sbd_delay_start,
                 True,
-                [0, 2, 3]
+                [
+                    SBDCheckItem.SBD_DISK_METADATA,
+                    SBDCheckItem.SBD_WATCHDOG_TIMEOUT,
+                    SBDCheckItem.FENCE_SBD_AGENT
+                ]
             ),
 
             (
@@ -540,7 +575,7 @@
                 self._check_sbd_systemd_start_timeout,
                 self._fix_sbd_systemd_start_timeout,
                 True,
-                [4]
+                [SBDCheckItem.SBD_DELAY_START]
             ),
 
             (
@@ -548,7 +583,7 @@
                 self._check_stonith_watchdog_timeout,
                 self._fix_stonith_watchdog_timeout,
                 False,
-                [2]
+                [SBDCheckItem.SBD_WATCHDOG_TIMEOUT]
             ),
 
             (
@@ -556,7 +591,10 @@
                 self._check_stonith_timeout,
                 self._fix_stonith_timeout,
                 False,
-                [0, 2]
+                [
+                    SBDCheckItem.SBD_DISK_METADATA,
+                    SBDCheckItem.SBD_WATCHDOG_TIMEOUT
+                ]
             ),
 
             (
@@ -584,6 +622,7 @@
             ),
         ]
 
+    def check_and_fix(self) -> CheckResult:
         if not ServiceManager().service_is_active(constants.SBD_SERVICE):
             if self.fix:
                 raise FixAborted("%s is not active, skip fixing SBD timeout 
issues" % constants.SBD_SERVICE)
@@ -605,9 +644,11 @@
 
         self._load_configurations_from_runtime()
 
-        check_res_list = [CheckResult.SUCCESS for _ in 
range(len(checks_and_fixes))]
-        for index, (name, check_method, fix_method, ssh_required, 
prereq_checks) in enumerate(checks_and_fixes):
-            if prereq_checks and any(check_res_list[i] != CheckResult.SUCCESS 
for i in prereq_checks):
+        check_and_fix_items = self._check_and_fix_items()
+        check_res_list = [CheckResult.SUCCESS for _ in 
range(len(check_and_fix_items))]
+        for index, (name, check_method, fix_method, ssh_required, 
prereq_checks) in enumerate(check_and_fix_items):
+            if prereq_checks and any(check_res_list[p.value] != 
CheckResult.SUCCESS for p in prereq_checks):
+                check_res_list[index] = CheckResult.ERROR
                 continue
             check_res = check_method()
             logger.debug("SBD Checking: %s, result: %s", name, check_res)
@@ -626,7 +667,7 @@
                 else:
                     raise FixFailure(f"Failed to fix {name} issue")
 
-        return SBDTimeoutChecker._return_helper(check_res_list)
+        return SBDConfigChecker._return_helper(check_res_list)
 
     def _check_config_consistency(self, error_msg: str = "") -> bool:
         consistent = True
@@ -674,12 +715,18 @@
         if self.disk_based:
             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 required that SBD watchdog timeout(now 
%d) >= %d", self.sbd_watchdog_timeout, self.sbd_watchdog_timeout_expected)
+                self._log_when_not_quiet(
+                    logging.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 required that SBD msgwait(now %d) >= 
%d", self.sbd_msgwait, self.sbd_msgwait_expected)
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "It's required that SBD msgwait(now %d) >= %d",
+                    self.sbd_msgwait, self.sbd_msgwait_expected
+                )
                 return CheckResult.ERROR
         return CheckResult.SUCCESS
 
@@ -699,8 +746,11 @@
         if not self.disk_based:
             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 required that SBD_WATCHDOG_TIMEOUT(now 
%d) >= %d", self.sbd_watchdog_timeout, self.sbd_watchdog_timeout_expected)
+                self._log_when_not_quiet(
+                    logging.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
 
@@ -714,19 +764,25 @@
             return CheckResult.SUCCESS
         elif config_value.isdigit() and expected_value.isdigit():
             if int(config_value) < int(expected_value):
-                if not self.quiet:
-                    logger.error("It's required that SBD_DELAY_START is set to 
%s, now is %s",
-                                 expected_value, config_value)
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "It's required that SBD_DELAY_START is set to %s, now is 
%s",
+                    expected_value, config_value
+                )
                 return CheckResult.ERROR
             else:
-                if not self.quiet:
-                    logger.warning("It's recommended that SBD_DELAY_START is 
set to %s, now is %s",
-                                   expected_value, config_value)
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "It's recommended that SBD_DELAY_START is set to %s, now 
is %s",
+                    expected_value, config_value
+                )
                 return CheckResult.WARNING
         else:
-            if not self.quiet:
-                logger.error("It's required that SBD_DELAY_START is set to %s, 
now is %s",
-                            expected_value, config_value)
+            self._log_when_not_quiet(
+                logging.ERROR,
+                "It's required that SBD_DELAY_START is set to %s, now is %s",
+                expected_value, config_value
+            )
             return CheckResult.ERROR
 
     def _fix_sbd_delay_start(self):
@@ -741,21 +797,21 @@
             if actual_start_timeout == expected_start_timeout:
                 check_res_list.append(CheckResult.SUCCESS)
             elif actual_start_timeout < expected_start_timeout:
-                if not self.quiet:
-                    logger.error(
-                        "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
-                    )
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "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)
             else:
-                if not self.quiet:
-                    logger.warning(
-                        "It's recommended that systemd start timeout for 
sbd.service is set to %ds, now is %ds on node %s",
-                        expected_start_timeout, actual_start_timeout, node
-                    )
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "It's recommended 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.WARNING)
 
-        return SBDTimeoutChecker._return_helper(check_res_list)
+        return SBDConfigChecker._return_helper(check_res_list)
 
     def _fix_sbd_systemd_start_timeout(self):
         logger.info("Adjusting systemd start timeout for sbd.service to %ds", 
self.sbd_systemd_start_timeout_expected)
@@ -768,30 +824,41 @@
     def _check_stonith_watchdog_timeout(self) -> CheckResult:
         value = utils.get_property("stonith-watchdog-timeout")
         if value and int(value) == -1:
-            if not self.quiet:
-                logger.warning("It's recommended that stonith-watchdog-timeout 
is et to %d, now is -1", self.stonith_watchdog_timeout)
+            self._log_when_not_quiet(
+                logging.WARNING,
+                "It's recommended that stonith-watchdog-timeout is set to %d, 
now is -1",
+                self.stonith_watchdog_timeout
+            )
             return CheckResult.WARNING
         value = int(utils.crm_msec(value)/1000)
         if self.disk_based:
             if value > 0:
-                if not self.quiet:
-                    logger.warning("It's recommended that 
stonith-watchdog-timeout is not set when using disk-based SBD")
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "It's recommended that stonith-watchdog-timeout is not set 
when using disk-based SBD"
+                )
                 return CheckResult.WARNING
         else:
             if value == 0:
-                if not self.quiet:
-                    logger.error("It's required that stonith-watchdog-timeout 
is set to %d, now is not set",
-                                self.stonith_watchdog_timeout)
+                self._log_when_not_quiet(
+                    logging.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 required that stonith-watchdog-timeout 
is set to %d, now is %d",
-                                 self.stonith_watchdog_timeout, value)
+                self._log_when_not_quiet(
+                    logging.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:
-                if not self.quiet:
-                    logger.warning("It's recommended that 
stonith-watchdog-timeout is set to %d, now is %d",
-                                   self.stonith_watchdog_timeout, value)
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "It's recommended that stonith-watchdog-timeout is set to 
%d, now is %d",
+                    self.stonith_watchdog_timeout, value
+                )
                 return CheckResult.WARNING
         return CheckResult.SUCCESS
 
@@ -809,14 +876,18 @@
         # will get default value from pacemaker metadata if not set
         value = int(utils.crm_msec(value)/1000)
         if value < expected_value:
-            if not self.quiet:
-                logger.error("It's required that stonith-timeout is set to %d, 
now is %d",
-                             expected_value, value)
+            self._log_when_not_quiet(
+                logging.ERROR,
+                "It's required that stonith-timeout is set to %d, now is %d",
+                expected_value, value
+            )
             return CheckResult.ERROR
         elif value > expected_value:
-            if not self.quiet:
-                logger.warning("It's recommended that stonith-timeout is set 
to %d, now is %d",
-                               expected_value, value)
+            self._log_when_not_quiet(
+                logging.WARNING,
+                "It's recommended that stonith-timeout is set to %d, now is 
%d",
+                expected_value, value
+            )
             return CheckResult.WARNING
         return CheckResult.SUCCESS
 
@@ -828,8 +899,10 @@
     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")
+            self._log_when_not_quiet(
+                logging.ERROR,
+                "It's required that stonith-enabled is set to true, now is 
false"
+            )
             return CheckResult.ERROR
         return CheckResult.SUCCESS
 
@@ -849,12 +922,14 @@
             if rc == 0:
                 check_res_list.append(CheckResult.SUCCESS)
             else:
-                if not self.quiet:
-                    logger.warning("Runtime drop-in file %s to unset 
SBD_DELAY_START is missing on node %s",
-                                   
SBDManager.SBD_SYSTEMD_DELAY_START_DISABLE_FILE, node)
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "Runtime drop-in file %s to unset SBD_DELAY_START is 
missing on node %s",
+                    SBDManager.SBD_SYSTEMD_DELAY_START_DISABLE_FILE, node
+                )
                 check_res_list.append(CheckResult.WARNING)
 
-        return SBDTimeoutChecker._return_helper(check_res_list)
+        return SBDConfigChecker._return_helper(check_res_list)
 
     def _fix_sbd_delay_start_unset_dropin(self):
         logger.info("Createing runtime drop-in file %s to unset 
SBD_DELAY_START",
@@ -868,11 +943,14 @@
             if service_manager.service_is_enabled(constants.SBD_SERVICE, node):
                 check_res_list.append(CheckResult.SUCCESS)
             else:
-                if not self.quiet:
-                    logger.error("%s is not enabled on node %s", 
constants.SBD_SERVICE, node)
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "%s is not enabled on node %s",
+                    constants.SBD_SERVICE, node
+                )
                 self.service_disabled_node_list.append(node)
                 check_res_list.append(CheckResult.ERROR)
-        return SBDTimeoutChecker._return_helper(check_res_list)
+        return SBDConfigChecker._return_helper(check_res_list)
 
     def _fix_sbd_service_is_enabled(self):
         service_manager = ServiceManager()
@@ -891,16 +969,25 @@
             if configured:
                 return CheckResult.SUCCESS
             else:
-                if not self.quiet:
-                    logger.error("Fence agent %s is not configured", 
SBDManager.SBD_RA)
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "Fence agent %s is not configured",
+                    SBDManager.SBD_RA
+                )
                 return CheckResult.ERROR
         if not xml_inst.is_resource_configured(SBDManager.SBD_RA):
-            if not self.quiet:
-                logger.error("Fence agent %s is not configured", 
SBDManager.SBD_RA)
+            self._log_when_not_quiet(
+                logging.ERROR,
+                "Fence agent %s is not configured",
+                SBDManager.SBD_RA
+            )
             return CheckResult.ERROR
         elif not xml_inst.is_resource_started(SBDManager.SBD_RA) and not 
utils.is_cluster_in_maintenance_mode():
-            if not self.quiet:
-                logger.error("Fence agent %s is not started", 
SBDManager.SBD_RA)
+            self._log_when_not_quiet(
+                logging.ERROR,
+                "Fence agent %s is not started",
+                SBDManager.SBD_RA
+            )
             return CheckResult.ERROR
         return CheckResult.SUCCESS
 
@@ -1020,7 +1107,6 @@
     def initialize_sbd(self):
         if self.diskless_sbd:
             logger.info("Configuring diskless SBD")
-            self._warn_diskless_sbd()
             return
         elif self.device_list_to_init:
             logger.info("Configuring disk-based SBD")
@@ -1047,34 +1133,16 @@
                 logger.info("Enable %s on node %s", constants.SBD_SERVICE, 
node)
                 service_manager.enable_service(constants.SBD_SERVICE, node)
 
-    def configure_sbd(self):
-        '''
-        Configure fence_sbd resource and related properties
-        '''
-        if SBDUtils.get_sbd_device_from_config():
-            if utils.get_property("stonith-watchdog-timeout", 
get_default=False):
-                utils.delete_property("stonith-watchdog-timeout")
-            if not 
xmlutil.CrmMonXmlParser().is_resource_configured(self.SBD_RA):
-                cmd = f"crm configure primitive {self.SBD_RA_ID} {self.SBD_RA}"
-                sh.cluster_shell().get_stdout_or_raise_error(cmd)
-        else:
-            swt_value = self.timeout_dict.get("stonith-watchdog", 
2*SBDTimeout.get_sbd_watchdog_timeout())
-            utils.set_property("stonith-watchdog-timeout", swt_value)
-        utils.set_property("stonith-enabled", "true")
-
-    def _warn_diskless_sbd(self, peer=None):
+    @staticmethod
+    def warn_diskless_sbd():
         '''
         Give warning when configuring diskless sbd
         '''
-        # When in sbd stage or join process
-        if (self.diskless_sbd and self.cluster_is_running) or peer:
-            vote_dict = utils.get_quorum_votes_dict(peer)
+        if SBDUtils.is_using_diskless_sbd():
+            vote_dict = utils.get_quorum_votes_dict()
             expected_vote = int(vote_dict.get('Expected', 0))
-            if expected_vote < self.DISKLESS_SBD_MIN_EXPECTED_VOTE:
-                logger.warning('%s', self.DISKLESS_SBD_WARNING)
-        # When in init process
-        elif self.diskless_sbd:
-            logger.warning('%s', self.DISKLESS_SBD_WARNING)
+            if expected_vote < SBDManager.DISKLESS_SBD_MIN_EXPECTED_VOTE:
+                logger.warning('%s', SBDManager.DISKLESS_SBD_WARNING)
 
     def _warn_and_raise_no_sbd(self):
         logger.warning('%s', self.NO_SBD_WARNING)
@@ -1235,8 +1303,6 @@
 
         if dev_list:
             SBDUtils.verify_sbd_device(dev_list, [peer_host])
-        else:
-            self._warn_diskless_sbd(peer_host)
 
         logger.info("Got {}SBD configuration".format("" if dev_list else 
"diskless "))
         self.enable_sbd_service()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260209.ed56b53c/crmsh/ui_cluster.py 
new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/ui_cluster.py
--- old/crmsh-5.0.0+20260209.ed56b53c/crmsh/ui_cluster.py       2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/ui_cluster.py       2026-02-26 
10:31:40.000000000 +0100
@@ -352,8 +352,8 @@
     firewalld   Add high-availability service to firewalld
     csync2      Configure csync2
     corosync    Configure corosync
-    sbd         Configure SBD (requires -s <dev>)
     cluster     Bring the cluster online
+    sbd         Configure SBD (requires -s <dev>)
     ocfs2       Configure OCFS2 (requires -o <dev>) NOTE: this is a Technical 
Preview
     gfs2        Configure GFS2 (requires -g <dev>) NOTE: this is a Technical 
Preview
     admin       Create administration virtual IP (optional)
@@ -847,7 +847,7 @@
             case 'sbd':
                 fix = parsed_args.fix
                 try:
-                    result = sbd.SBDTimeoutChecker(quiet=fix, 
fix=fix).check_and_fix()
+                    result = sbd.SBDConfigChecker(quiet=fix, 
fix=fix).check_and_fix()
                 except sbd.FixFailure as e:
                     logger.error('%s', e)
                     return False
@@ -855,7 +855,7 @@
                     logger.error('%s', e)
                     logger.error('SBD: Check sbd timeout configuration: FAIL.')
                     return False
-                return sbd.SBDTimeoutChecker.log_and_return(result, fix)
+                return sbd.SBDConfigChecker.log_and_return(result, fix)
 
             case 'sles16':
                 try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260209.ed56b53c/crmsh/ui_sbd.py 
new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/ui_sbd.py
--- old/crmsh-5.0.0+20260209.ed56b53c/crmsh/ui_sbd.py   2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/crmsh/ui_sbd.py   2026-02-26 
10:31:40.000000000 +0100
@@ -259,11 +259,11 @@
     def check_timeout_configurations() -> bool:
         check_rc = sbd.CheckResult.SUCCESS
         try:
-            check_rc = sbd.SBDTimeoutChecker().check_and_fix()
+            check_rc = sbd.SBDConfigChecker().check_and_fix()
         except sbd.FixAborted as e:
             logger.error('%s', e)
             return False
-        return sbd.SBDTimeoutChecker.log_and_return(check_rc)
+        return sbd.SBDConfigChecker.log_and_return(check_rc)
 
     def _parse_args(self, args: tuple[str, ...]) -> dict[str, int|str]:
         '''
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/features/bootstrap_options.feature 
new/crmsh-5.0.0+20260226.8b99a4c5/test/features/bootstrap_options.feature
--- old/crmsh-5.0.0+20260209.ed56b53c/test/features/bootstrap_options.feature   
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/features/bootstrap_options.feature   
2026-02-26 10:31:40.000000000 +0100
@@ -34,8 +34,8 @@
       """
     When    Try "crm cluster init -N hanode2" on "hanode1"
     Then    Expected "Can't use -N/--nodes option without -y/--yes option" in 
stderr
-    When    Try "crm cluster init sbd -N hanode1 -N hanode2 -y" on "hanode1"
-    Then    Expected "Can't use -N/--nodes option and stage(sbd) together" in 
stderr
+    When    Try "crm cluster init cluster -N hanode1 -N hanode2 -y" on 
"hanode1"
+    Then    Expected "Can't use -N/--nodes option and stage(cluster) together" 
in stderr
     When    Try "crm corosync link help add" on "hanode1"
     Then    Expected return code is "0"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/features/bootstrap_sbd_delay.feature 
new/crmsh-5.0.0+20260226.8b99a4c5/test/features/bootstrap_sbd_delay.feature
--- old/crmsh-5.0.0+20260209.ed56b53c/test/features/bootstrap_sbd_delay.feature 
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/features/bootstrap_sbd_delay.feature 
2026-02-26 10:31:40.000000000 +0100
@@ -15,13 +15,13 @@
     Then    Cluster service is "started" on "hanode1"
     And     Service "sbd" is "started" on "hanode1"
     And     Resource "stonith-sbd" type "fence_sbd" is "Started"
-    And     SBD option "SBD_DELAY_START" value is "no"
+    And     SBD option "SBD_DELAY_START" value is "41"
     And     SBD option "SBD_WATCHDOG_TIMEOUT" value is "5"
     And     SBD option "msgwait" value for "/dev/sda1" is "30"
     # original value is 43, which is calculated by external/sbd RA
     # now fence_sbd doesn't calculate it, so this value is the default one
     # from pacemaker
-    And     Cluster property "stonith-timeout" is "60"
+    And     Cluster property "stonith-timeout" is "71"
     And     Parameter "pcmk_delay_max" not configured in "stonith-sbd"
 
     Given   Has disk "/dev/sda1" on "hanode2"
@@ -78,7 +78,7 @@
     And     Parameter "pcmk_delay_max" configured in "stonith-sbd"
 
   @clean
-  Scenario: disk-less SBD with small sbd_watchdog_timeout
+  Scenario: diskless SBD with small sbd_watchdog_timeout
     Given   Run "test -f /etc/crm/profiles.yml" OK
     Given   Yaml "default:corosync.totem.token" value is "5000"
     Given   Yaml "default:sbd.watchdog_timeout" value is "15"
@@ -86,17 +86,17 @@
     Given   Cluster service is "stopped" on "hanode1"
     When    Run "crm cluster init -S -y" on "hanode1"
     Then    Cluster service is "started" on "hanode1"
-    And     SBD option "SBD_DELAY_START" value is "no"
+    And     SBD option "SBD_DELAY_START" value is "41"
     And     SBD option "SBD_WATCHDOG_TIMEOUT" value is "15"
-    And     Cluster property "stonith-timeout" is "60"
+    And     Cluster property "stonith-timeout" is "71"
 
     Given   Cluster service is "stopped" on "hanode2"
     When    Run "crm cluster join -c hanode1 -y" on "hanode2"
     Then    Cluster service is "started" on "hanode2"
-    # SBD_DELAY_START >= (token + consensus + 2*SBD_WATCHDOG_TIMEOUT) # for 
disk-less sbd
+    # SBD_DELAY_START >= (token + consensus + 2*SBD_WATCHDOG_TIMEOUT) # for 
diskless sbd
     And     SBD option "SBD_DELAY_START" value is "41"
     And     SBD option "SBD_WATCHDOG_TIMEOUT" value is "15"
-    # stonith-timeout >= 1.2 * max(stonith_watchdog_timeout, 
2*SBD_WATCHDOG_TIMEOUT)  # for disk-less sbd
+    # stonith-timeout >= 1.2 * max(stonith_watchdog_timeout, 
2*SBD_WATCHDOG_TIMEOUT)  # for diskless sbd
     # stonith_timeout >= max(value_from_sbd, 
constants.STONITH_TIMEOUT_DEFAULT) + token + consensus
     And     Cluster property "stonith-timeout" is "71"
 
@@ -114,7 +114,7 @@
     And     Cluster property "stonith-timeout" is "71"
 
     When    Try "crm configure property stonith-watchdog-timeout=1" on 
"hanode1"
-    Then    Except "Can't set stonith-watchdog-timeout to 1 because it is less 
than SBD_WATCHDOG_TIMEOUT(now: 15)" in stderr
+    Then    Except "It's required to set stonith-watchdog-timeout to at least 
2*SBD_WATCHDOG_TIMEOUT: 30" in stderr
 
   @clean
   Scenario: disk-based SBD with big sbd_watchdog_timeout
@@ -128,13 +128,13 @@
     Then    Cluster service is "started" on "hanode1"
     And     Service "sbd" is "started" on "hanode1"
     And     Resource "stonith-sbd" type "fence_sbd" is "Started"
-    And     SBD option "SBD_DELAY_START" value is "no"
+    And     SBD option "SBD_DELAY_START" value is "131"
     And     SBD option "SBD_WATCHDOG_TIMEOUT" value is "5"
     And     SBD option "msgwait" value for "/dev/sda1" is "120"
     # original value is 172, which is calculated by external/sbd RA
     # now fence_sbd doesn't calculate it, so this value is the default one
     # from pacemaker
-    And     Cluster property "stonith-timeout" is "60"
+    And     Cluster property "stonith-timeout" is "155"
     And     Parameter "pcmk_delay_max" not configured in "stonith-sbd"
 
     Given   Has disk "/dev/sda1" on "hanode2"
@@ -230,7 +230,7 @@
     And     Parameter "pcmk_delay_max" not configured in "stonith-sbd"
 
   @clean
-  Scenario: Add disk-less sbd with qdevice
+  Scenario: Add diskless sbd with qdevice
     Given   Run "test -f /etc/crm/profiles.yml" OK
     Given   Yaml "default:corosync.totem.token" value is "5000"
     Given   Yaml "default:sbd.watchdog_timeout" value is "15"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/features/bootstrap_sbd_normal.feature 
new/crmsh-5.0.0+20260226.8b99a4c5/test/features/bootstrap_sbd_normal.feature
--- 
old/crmsh-5.0.0+20260209.ed56b53c/test/features/bootstrap_sbd_normal.feature    
    2026-02-09 08:58:33.000000000 +0100
+++ 
new/crmsh-5.0.0+20260226.8b99a4c5/test/features/bootstrap_sbd_normal.feature    
    2026-02-26 10:31:40.000000000 +0100
@@ -82,8 +82,8 @@
     Given   Cluster service is "stopped" on "hanode2"
     When    Run "crm cluster init ssh -y" on "hanode1"
     And     Run "crm cluster init corosync -y" on "hanode1"
-    And     Run "crm cluster init sbd -s /dev/sda1 -y" on "hanode1"
     And     Run "crm cluster init cluster -y" on "hanode1"
+    And     Run "crm cluster init sbd -s /dev/sda1 -y" on "hanode1"
     Then    Cluster service is "started" on "hanode1"
     And     Service "sbd" is "started" on "hanode1"
     When    Run "crm cluster join ssh -y -c hanode1" on "hanode2"
@@ -99,8 +99,8 @@
     Given   Cluster service is "stopped" on "hanode2"
     When    Run "crm cluster init ssh -y" on "hanode1"
     And     Run "crm cluster init corosync -y" on "hanode1"
-    And     Run "crm cluster init sbd -S -y" on "hanode1"
     And     Run "crm cluster init cluster -y" on "hanode1"
+    And     Run "crm cluster init sbd -S -y" on "hanode1"
     Then    Cluster service is "started" on "hanode1"
     And     Service "sbd" is "started" on "hanode1"
     When    Run "crm cluster join ssh -y -c hanode1" on "hanode2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/features/steps/const.py 
new/crmsh-5.0.0+20260226.8b99a4c5/test/features/steps/const.py
--- old/crmsh-5.0.0+20260209.ed56b53c/test/features/steps/const.py      
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/features/steps/const.py      
2026-02-26 10:31:40.000000000 +0100
@@ -157,8 +157,8 @@
     firewalld   Add high-availability service to firewalld
     csync2      Configure csync2
     corosync    Configure corosync
-    sbd         Configure SBD (requires -s <dev>)
     cluster     Bring the cluster online
+    sbd         Configure SBD (requires -s <dev>)
     ocfs2       Configure OCFS2 (requires -o <dev>) NOTE: this is a Technical 
Preview
     gfs2        Configure GFS2 (requires -g <dev>) NOTE: this is a Technical 
Preview
     admin       Create administration virtual IP (optional)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/run-functional-tests 
new/crmsh-5.0.0+20260226.8b99a4c5/test/run-functional-tests
--- old/crmsh-5.0.0+20260209.ed56b53c/test/run-functional-tests 2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/run-functional-tests 2026-02-26 
10:31:40.000000000 +0100
@@ -363,7 +363,7 @@
                podman_exec $node_name "sed -i s/$item/$ip/g $2"
        done
 
-       vip_replace_array=(`podman_exec $node_name "grep -o -E '@vip\.[0-9]' 
$2|sort -u|dos2unix"`)
+       vip_replace_array=(`podman_exec $node_name "grep -o -E '@vip\.[0-9]' 
$2|sort -u"`)
        for item in ${vip_replace_array[@]};do
                index=`echo $item|cut -d "." -f 2|tr -d "\r"`
                suffix=$((123+index))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/unittests/test_bootstrap.py 
new/crmsh-5.0.0+20260226.8b99a4c5/test/unittests/test_bootstrap.py
--- old/crmsh-5.0.0+20260209.ed56b53c/test/unittests/test_bootstrap.py  
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/unittests/test_bootstrap.py  
2026-02-26 10:31:40.000000000 +0100
@@ -1528,7 +1528,7 @@
         bootstrap.adjust_pcmk_delay_max(False)
         mock_run.assert_called_once_with("crm resource param res_1 delete 
pcmk_delay_max")
 
-    @mock.patch('crmsh.sbd.SBDTimeoutChecker')
+    @mock.patch('crmsh.sbd.SBDConfigChecker')
     @mock.patch('crmsh.service_manager.ServiceManager.service_is_active')
     def test_adjust_stonith_timeout_sbd(self, mock_is_active, 
mock_sbd_checker):
         mock_sbd_checker_inst = mock.Mock()
@@ -1577,13 +1577,14 @@
         bootstrap.adjust_properties()
         mock_is_active.assert_called_once_with("pacemaker.service")
 
+    @mock.patch('crmsh.sbd.SBDManager.warn_diskless_sbd')
     @mock.patch('crmsh.bootstrap.adjust_priority_fencing_delay')
     @mock.patch('crmsh.bootstrap.adjust_priority_in_rsc_defaults')
     @mock.patch('crmsh.bootstrap.adjust_stonith_timeout')
     @mock.patch('crmsh.bootstrap.adjust_pcmk_delay_max')
     @mock.patch('crmsh.utils.is_2node_cluster_without_qdevice')
     @mock.patch('crmsh.service_manager.ServiceManager.service_is_active')
-    def test_adjust_properties(self, mock_is_active, mock_2node_qdevice, 
mock_adj_pcmk, mock_adj_stonith, mock_adj_priority, mock_adj_fence):
+    def test_adjust_properties(self, mock_is_active, mock_2node_qdevice, 
mock_adj_pcmk, mock_adj_stonith, mock_adj_priority, mock_adj_fence, 
mock_warn_sbd):
         mock_is_active.return_value = True
         mock_2node_qdevice.return_value = True
         bootstrap.adjust_properties()
@@ -1592,6 +1593,7 @@
         mock_adj_stonith.assert_called_once_with()
         mock_adj_priority.assert_called_once_with(True)
         mock_adj_fence.assert_called_once_with(True)
+        mock_warn_sbd.assert_called_once_with()
 
     @mock.patch('crmsh.utils.cluster_copy_path')
     @mock.patch('crmsh.utils.fetch_cluster_node_list_from_node')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/unittests/test_sbd.py 
new/crmsh-5.0.0+20260226.8b99a4c5/test/unittests/test_sbd.py
--- old/crmsh-5.0.0+20260209.ed56b53c/test/unittests/test_sbd.py        
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/unittests/test_sbd.py        
2026-02-26 10:31:40.000000000 +0100
@@ -267,11 +267,11 @@
         self.assertEqual(result, 80)
 
 
-class TestSBDTimeoutChecker(unittest.TestCase):
+class TestSBDConfigChecker(unittest.TestCase):
 
     def setUp(self):
-        self.instance_check = sbd.SBDTimeoutChecker(fix=False)
-        self.instance_fix = sbd.SBDTimeoutChecker(fix=True)
+        self.instance_check = sbd.SBDConfigChecker(fix=False)
+        self.instance_fix = sbd.SBDConfigChecker(fix=True)
 
     @patch('logging.Logger.info')
     def test_log_and_return_success(self, mock_logger_info):
@@ -428,24 +428,24 @@
         self.assertTrue(self.instance_check._check_config_consistency("no peer 
nodes"))
         mock_logger_warning.assert_called_once_with("Skipping configuration 
consistency check: %s", "no peer nodes")
 
-    @patch('logging.Logger.error')
     @patch('crmsh.sbd.SBDTimeout.get_sbd_metadata_expected')
-    def test_check_sbd_disk_metadata_failure(self, 
mock_get_sbd_metadata_expected, mock_logger_error):
+    def test_check_sbd_disk_metadata_failure(self, 
mock_get_sbd_metadata_expected):
         self.instance_check.disk_based = True
+        self.instance_check._log_when_not_quiet = Mock()
         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 required that SBD 
watchdog timeout(now %d) >= %d", 10, 15)
-    
-    @patch('logging.Logger.error')
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"It's required that SBD watchdog timeout(now %d) >= %d", 10, 15)    
+
     @patch('crmsh.sbd.SBDTimeout.get_sbd_metadata_expected')
-    def test_check_sbd_disk_metadata_failure_msgwait(self, 
mock_get_sbd_metadata_expected, mock_logger_error):
+    def test_check_sbd_disk_metadata_failure_msgwait(self, 
mock_get_sbd_metadata_expected):
         self.instance_check.disk_based = True
+        self.instance_check._log_when_not_quiet = Mock()
         mock_get_sbd_metadata_expected.return_value = (10, 25)
         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 required that SBD 
msgwait(now %d) >= %d", 20, 25)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"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):
@@ -466,14 +466,14 @@
         self.instance_fix._fix_sbd_disk_metadata()
         mock_logger_info.assert_called_once_with("Adjusting sbd msgwait to %d, 
watchdog timeout to %d", 10, 5)
 
-    @patch('logging.Logger.error')
     @patch('crmsh.sbd.SBDTimeout.get_sbd_watchdog_timeout_expected')
-    def test_check_sbd_watchdog_timeout_failure(self, 
mock_get_sbd_watchdog_timeout_expected, mock_logger_error):
+    def test_check_sbd_watchdog_timeout_failure(self, 
mock_get_sbd_watchdog_timeout_expected):
         self.instance_check.disk_based = False
+        self.instance_check._log_when_not_quiet = Mock()
         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 required that 
SBD_WATCHDOG_TIMEOUT(now %d) >= %d", 3, 10)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"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):
@@ -488,24 +488,24 @@
         self.instance_fix._fix_sbd_watchdog_timeout()
         
mock_update_sbd_configuration.assert_called_once_with({"SBD_WATCHDOG_TIMEOUT": 
"10"})
 
-    @patch('logging.Logger.error')
-    def test_check_sbd_delay_start_failure(self, mock_logger_error):
+    def test_check_sbd_delay_start_failure(self):
         self.instance_check.sbd_delay_start_value_expected = "100"
         self.instance_check.sbd_delay_start_value_from_config = "30"
+        self.instance_check._log_when_not_quiet = Mock()
         self.assertEqual(self.instance_check._check_sbd_delay_start(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("It's required that 
SBD_DELAY_START is set to %s, now is %s", "100", "30")
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"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"
         self.instance_check.sbd_delay_start_value_from_config = "50"
         self.assertTrue(self.instance_check._check_sbd_delay_start())
 
-    @patch('logging.Logger.warning')
-    def test_check_sbd_delay_start_warning(self, mock_logger_warning):
+    def test_check_sbd_delay_start_warning(self):
         self.instance_check.sbd_delay_start_value_expected = "70"
         self.instance_check.sbd_delay_start_value_from_config = "80"
+        self.instance_check._log_when_not_quiet = Mock()
         self.assertEqual(self.instance_check._check_sbd_delay_start(), 
sbd.CheckResult.WARNING)
-        mock_logger_warning.assert_called_once_with("It's recommended that 
SBD_DELAY_START is set to %s, now is %s", "70", "80")
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.WARNING,
 "It's recommended that SBD_DELAY_START is set to %s, now is %s", "70", "80")
 
     @patch('crmsh.sbd.SBDManager.update_sbd_configuration')
     def test_fix_sbd_delay_start(self, mock_update_sbd_configuration):
@@ -513,23 +513,24 @@
         self.instance_fix._fix_sbd_delay_start()
         
mock_update_sbd_configuration.assert_called_once_with({"SBD_DELAY_START": "80"})
 
-    @patch('crmsh.sbd.SBDTimeoutChecker._return_helper')
-    @patch('logging.Logger.warning')
-    @patch('logging.Logger.error')
+    @patch('crmsh.sbd.SBDConfigChecker._return_helper')
     @patch('crmsh.sbd.SBDTimeout.get_sbd_systemd_start_timeout')
     @patch('crmsh.utils.this_node')
-    def test_check_sbd_systemd_start_timeout(self, mock_this_node, 
mock_get_sbd_systemd_start_timeout, mock_logger_error, mock_logger_warning, 
mock_return_helper):
+    def test_check_sbd_systemd_start_timeout(self, mock_this_node, 
mock_get_sbd_systemd_start_timeout, mock_return_helper):
         mock_this_node.return_value = 'node1'
         self.instance_check.sbd_systemd_start_timeout_expected = 60
         self.instance_check.peer_node_list = ['node2', 'node3']
         self.instance_check.quiet = False
+        self.instance_check._log_when_not_quiet = Mock()
         mock_get_sbd_systemd_start_timeout.side_effect = [60, 50, 70]
         mock_return_helper.return_value = sbd.CheckResult.ERROR
 
         
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 required that systemd 
start timeout for sbd.service is set to %ds, now is %ds on node %s", 60, 50, 
'node2')
+        self.instance_check._log_when_not_quiet.assert_has_calls([
+            call(logging.ERROR, "It's required that systemd start timeout for 
sbd.service is set to %ds, now is %ds on node %s", 60, 50, 'node2'),
+            call(logging.WARNING, "It's recommended that systemd start timeout 
for sbd.service is set to %ds, now is %ds on node %s", 60, 70, 'node3')
+        ])
 
     @patch('crmsh.utils.cluster_run_cmd')
     @patch('crmsh.bootstrap.sync_path')
@@ -543,22 +544,22 @@
         self.instance_fix._fix_sbd_systemd_start_timeout()
         mock_logger_info.assert_called_once_with("Adjusting systemd start 
timeout for sbd.service to %ds", 120)
 
-    @patch('logging.Logger.warning')
     @patch('crmsh.utils.get_property')
-    def test_check_stonith_watchdog_timeout_disk_based_failure(self, 
mock_get_property, mock_logger_warning):
+    def test_check_stonith_watchdog_timeout_disk_based_failure(self, 
mock_get_property):
         self.instance_check.disk_based = True
         mock_get_property.return_value = 5
+        self.instance_check._log_when_not_quiet = Mock()
         
self.assertEqual(self.instance_check._check_stonith_watchdog_timeout(), 
sbd.CheckResult.WARNING)
-        mock_logger_warning.assert_called_once_with("It's recommended that 
stonith-watchdog-timeout is not set when using disk-based SBD")
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.WARNING,
 "It's recommended that stonith-watchdog-timeout is not set when using 
disk-based SBD")
 
-    @patch('logging.Logger.error')
     @patch('crmsh.utils.get_property')
-    def test_check_stonith_watchdog_timeout_disk_less_failure(self, 
mock_get_property, mock_logger_error):
+    def test_check_stonith_watchdog_timeout_disk_less_failure(self, 
mock_get_property):
         self.instance_check.disk_based = False
         self.instance_check.stonith_watchdog_timeout = 15
         mock_get_property.return_value = ""
+        self.instance_check._log_when_not_quiet = Mock()
         
self.assertEqual(self.instance_check._check_stonith_watchdog_timeout(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("It's required that 
stonith-watchdog-timeout is set to %d, now is not set", 15)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"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):
@@ -584,21 +585,21 @@
         mock_logger_info.assert_called_once_with("Adjusting 
stonith-watchdog-timeout to %d", 15)
         mock_set_property.assert_called_once_with('stonith-watchdog-timeout', 
15)
 
-    @patch('logging.Logger.error')
     @patch('crmsh.utils.get_property')
-    def test_check_stonith_timeout_failure(self, mock_get_property, 
mock_logger_error):
+    def test_check_stonith_timeout_failure(self, mock_get_property):
         self.instance_check.get_stonith_timeout_expected = 
Mock(return_value=60)
         mock_get_property.return_value = 30
+        self.instance_check._log_when_not_quiet = Mock()
         self.assertEqual(self.instance_check._check_stonith_timeout(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("It's required that 
stonith-timeout is set to %d, now is %d", 60, 30)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"It's required that stonith-timeout is set to %d, now is %d", 60, 30)
 
-    @patch('logging.Logger.warning')
     @patch('crmsh.utils.get_property')
-    def test_check_stonith_timeout_warning(self, mock_get_property, 
mock_logger_warning):
+    def test_check_stonith_timeout_warning(self, mock_get_property):
         self.instance_check.get_stonith_timeout_expected = 
Mock(return_value=80)
         mock_get_property.return_value = 90
+        self.instance_check._log_when_not_quiet = Mock()
         self.assertEqual(self.instance_check._check_stonith_timeout(), 
sbd.CheckResult.WARNING)
-        mock_logger_warning.assert_called_once_with("It's recommended that 
stonith-timeout is set to %d, now is %d", 80, 90)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.WARNING,
 "It's recommended that stonith-timeout is set to %d, now is %d", 80, 90)
 
     @patch('crmsh.utils.get_property')
     def test_check_stonith_timeout_success(self, mock_get_property):
@@ -619,24 +620,24 @@
         mock_is_sbd_delay_start.return_value = False
         
self.assertEqual(self.instance_check._check_sbd_delay_start_unset_dropin(), 
sbd.CheckResult.SUCCESS)
 
-    @patch('crmsh.sbd.SBDTimeoutChecker._return_helper')
-    @patch('logging.Logger.warning')
+    @patch('crmsh.sbd.SBDConfigChecker._return_helper')
     @patch('crmsh.utils.this_node')
     @patch('crmsh.sh.cluster_shell')
     @patch('crmsh.sbd.SBDTimeout.is_sbd_delay_start')
-    def test_check_sbd_delay_start_unset_dropin(self, mock_is_sbd_delay_start, 
mock_cluster_shell, mock_this_node, mock_logger_warning, mock_return_helper):
+    def test_check_sbd_delay_start_unset_dropin(self, mock_is_sbd_delay_start, 
mock_cluster_shell, mock_this_node, mock_return_helper):
         mock_is_sbd_delay_start.return_value = True
         mock_this_node.return_value = 'node1'
         mock_cluster_shell_inst = Mock()
         mock_cluster_shell.return_value = mock_cluster_shell_inst
         self.instance_check.peer_node_list = ['node2']
         self.instance_check.quiet = False
+        self.instance_check._log_when_not_quiet = Mock()
         mock_cluster_shell_inst.get_rc_and_error.side_effect = [(0, None), (1, 
None)]
         mock_return_helper.return_value = sbd.CheckResult.WARNING
 
         
self.assertEqual(self.instance_check._check_sbd_delay_start_unset_dropin(), 
sbd.CheckResult.WARNING)
 
-        mock_logger_warning.assert_called_once_with("Runtime drop-in file %s 
to unset SBD_DELAY_START is missing on node %s", 
sbd.SBDManager.SBD_SYSTEMD_DELAY_START_DISABLE_FILE, 'node2')
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.WARNING,
 "Runtime drop-in file %s to unset SBD_DELAY_START is missing on node %s", 
sbd.SBDManager.SBD_SYSTEMD_DELAY_START_DISABLE_FILE, 'node2')
 
     @patch('crmsh.sbd.SBDManager.unset_sbd_delay_start')
     @patch('logging.Logger.info')
@@ -648,20 +649,20 @@
         self.instance_check.disk_based = False
         self.assertEqual(self.instance_check._check_fence_sbd(), 
sbd.CheckResult.SUCCESS)
 
-    @patch('crmsh.sbd.SBDTimeoutChecker._return_helper')
-    @patch('logging.Logger.error')
+    @patch('crmsh.sbd.SBDConfigChecker._return_helper')
     @patch('crmsh.utils.this_node')
     @patch('crmsh.sbd.ServiceManager')
-    def test_check_sbd_service_is_enabled(self, mock_ServiceManager, 
mock_this_node, mock_logger_error, mock_return_helper):
+    def test_check_sbd_service_is_enabled(self, mock_ServiceManager, 
mock_this_node, mock_return_helper):
         mock_this_node.return_value = 'node1'
         mock_service_manager_inst = Mock()
         mock_ServiceManager.return_value = mock_service_manager_inst
         self.instance_check.peer_node_list = ['node2']
         self.instance_check.quiet = False
+        self.instance_check._log_when_not_quiet = Mock()
         mock_service_manager_inst.service_is_enabled.side_effect = [True, 
False]
         mock_return_helper.return_value = sbd.CheckResult.ERROR
         self.assertEqual(self.instance_check._check_sbd_service_is_enabled(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("%s is not enabled on node 
%s", constants.SBD_SERVICE, 'node2')
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"%s is not enabled on node %s", constants.SBD_SERVICE, 'node2')
 
     @patch('logging.Logger.info')
     @patch('crmsh.sbd.ServiceManager')
@@ -673,27 +674,27 @@
         self.instance_fix._fix_sbd_service_is_enabled()
         mock_logger_info.assert_called_once_with("Enabling %s on node %s", 
constants.SBD_SERVICE, 'node2')
 
-    @patch('logging.Logger.error')
     @patch('crmsh.xmlutil.CrmMonXmlParser')
-    def test_check_fence_sbd_not_configured(self, mock_CrmMonXmlParser, 
mock_logger_error):
+    def test_check_fence_sbd_not_configured(self, mock_CrmMonXmlParser):
         self.instance_check.disk_based = True
         self.instance_check.quiet = False
+        self.instance_check._log_when_not_quiet = Mock()
         mock_parser_instance = Mock()
         mock_CrmMonXmlParser.return_value = mock_parser_instance
         mock_parser_instance.not_connected.return_value = False
         mock_parser_instance.is_resource_configured.return_value = False
         self.assertEqual(self.instance_check._check_fence_sbd(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("Fence agent %s is not 
configured", sbd.SBDManager.SBD_RA)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"Fence agent %s is not configured", sbd.SBDManager.SBD_RA)
 
-    @patch('logging.Logger.error')
     @patch('crmsh.cibquery.get_primitives_with_ra')
     @patch('crmsh.cibquery.ResourceAgent')
     @patch('crmsh.xmlutil.text2elem')
     @patch('crmsh.sh.cluster_shell')
     @patch('crmsh.xmlutil.CrmMonXmlParser')
-    def test_check_fence_sbd_not_configured_cluster_offline(self, 
mock_CrmMonXmlParser, mock_cluster_shell, mock_text2elem, mock_ResourceAgent, 
mock_get_primitives_with_ra, mock_logger_error):
+    def test_check_fence_sbd_not_configured_cluster_offline(self, 
mock_CrmMonXmlParser, mock_cluster_shell, mock_text2elem, mock_ResourceAgent, 
mock_get_primitives_with_ra):
         self.instance_check.disk_based = True
         self.instance_check.quiet = False
+        self.instance_check._log_when_not_quiet = Mock()
         mock_parser_instance = Mock()
         mock_CrmMonXmlParser.return_value = mock_parser_instance
         mock_parser_instance.not_connected.return_value = True
@@ -705,7 +706,7 @@
         mock_ResourceAgent.return_value = mock_resource_agent_instance
         mock_get_primitives_with_ra.return_value = []
         self.assertEqual(self.instance_check._check_fence_sbd(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("Fence agent %s is not 
configured", sbd.SBDManager.SBD_RA)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"Fence agent %s is not configured", sbd.SBDManager.SBD_RA)
 
     @patch('crmsh.cibquery.get_primitives_with_ra')
     @patch('crmsh.cibquery.ResourceAgent')
@@ -726,18 +727,18 @@
         mock_get_primitives_with_ra.return_value = ['fence_sbd_0']
         self.assertEqual(self.instance_check._check_fence_sbd(), 
sbd.CheckResult.SUCCESS)
 
-    @patch('logging.Logger.error')
     @patch('crmsh.xmlutil.CrmMonXmlParser')
-    def test_check_fence_sbd_not_started(self, mock_CrmMonXmlParser, 
mock_logger_error):
+    def test_check_fence_sbd_not_started(self, mock_CrmMonXmlParser):
         self.instance_check.disk_based = True
         self.instance_check.quiet = False
+        self.instance_check._log_when_not_quiet = Mock()
         mock_parser_instance = Mock()
         mock_CrmMonXmlParser.return_value = mock_parser_instance
         mock_parser_instance.not_connected.return_value = False
         mock_parser_instance.is_resource_configured.return_value = True
         mock_parser_instance.is_resource_started.return_value = False
         self.assertEqual(self.instance_check._check_fence_sbd(), 
sbd.CheckResult.ERROR)
-        mock_logger_error.assert_called_once_with("Fence agent %s is not 
started", sbd.SBDManager.SBD_RA)
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"Fence agent %s is not started", sbd.SBDManager.SBD_RA)
 
     @patch('crmsh.xmlutil.CrmMonXmlParser')
     def test_check_fence_sbd_success(self, mock_CrmMonXmlParser):
@@ -787,14 +788,14 @@
         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):
+    def test_check_stonith_enabled_failure(self, mock_get_property, 
mock_is_boolean_false):
         mock_get_property.return_value = "false"
         mock_is_boolean_false.return_value = True
+        self.instance_check._log_when_not_quiet = Mock()
         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")
+        
self.instance_check._log_when_not_quiet.assert_called_once_with(logging.ERROR, 
"It's required that stonith-enabled is set to true, now is false")
 
     @patch('logging.Logger.info')
     @patch('crmsh.utils.set_property')
@@ -942,22 +943,13 @@
             sbdmanager_instance._warn_and_raise_no_sbd()
         mock_logger_warning.assert_called_once_with('%s', 
SBDManager.NO_SBD_WARNING)
 
-    @patch('crmsh.sbd.ServiceManager')
     @patch('crmsh.utils.get_quorum_votes_dict')
     @patch('logging.Logger.warning')
-    def test_warn_diskless_sbd(self, mock_logger_warning, 
mock_get_quorum_votes_dict, mock_ServiceManager):
-        mock_ServiceManager.return_value.service_is_active = 
MagicMock(return_value=True)
+    @patch('crmsh.sbd.SBDUtils.is_using_diskless_sbd')
+    def test_warn_diskless_sbd(self, mock_is_using_sbd, mock_logger_warning, 
mock_get_quorum_votes_dict):
+        mock_is_using_sbd.return_value = True
         mock_get_quorum_votes_dict.return_value = {'Expected': '2', 'Total': 
'2'}
-        sbdmanager_instance = SBDManager()
-        sbdmanager_instance._warn_diskless_sbd(peer="node1")
-        mock_logger_warning.assert_called_once_with('%s', 
SBDManager.DISKLESS_SBD_WARNING)
-
-    @patch('crmsh.sbd.ServiceManager')
-    @patch('logging.Logger.warning')
-    def test_warn_diskless_sbd_init(self, mock_logger_warning, 
mock_ServiceManager):
-        mock_ServiceManager.return_value.service_is_active = 
MagicMock(return_value=False)
-        sbdmanager_instance = SBDManager(diskless_sbd=True)
-        sbdmanager_instance._warn_diskless_sbd()
+        sbd.SBDManager.warn_diskless_sbd()
         mock_logger_warning.assert_called_once_with('%s', 
SBDManager.DISKLESS_SBD_WARNING)
 
     @patch('crmsh.sbd.SBDUtils.check_devices_metadata_consistent')
@@ -1130,36 +1122,6 @@
         sbdmanager_instance.initialize_sbd()
         mock_convert_timeout_dict_to_opt_str.assert_not_called()
 
-    @patch('crmsh.utils.set_property')
-    @patch('crmsh.sbd.ServiceManager')
-    @patch('crmsh.sbd.SBDTimeout.get_sbd_watchdog_timeout')
-    @patch('crmsh.sbd.SBDUtils.get_sbd_device_from_config')
-    def test_configure_sbd_diskless(self, mock_get_sbd_device, 
mock_get_sbd_watchdog_timeout, mock_ServiceManager, mock_set_property):
-        mock_get_sbd_watchdog_timeout.return_value = 1
-        mock_get_sbd_device.return_value = False
-        sbdmanager_instance = SBDManager()
-        sbdmanager_instance.configure_sbd()
-        mock_set_property.assert_has_calls([
-            call("stonith-watchdog-timeout", 2),
-            call("stonith-enabled", "true")
-        ])
-
-    @patch('crmsh.utils.delete_property')
-    @patch('crmsh.utils.get_property')
-    @patch('crmsh.sbd.sh.cluster_shell')
-    @patch('crmsh.sbd.xmlutil.CrmMonXmlParser')
-    @patch('crmsh.utils.set_property')
-    @patch('crmsh.sbd.ServiceManager')
-    @patch('crmsh.sbd.SBDUtils.get_sbd_device_from_config')
-    def test_configure_sbd(self, mock_get_sbd_device, mock_ServiceManager, 
mock_set_property, mock_CrmMonXmlParser, mock_cluster_shell, mock_get_property, 
mock_delete_property):
-        mock_get_sbd_device.return_value = True
-        mock_get_property.return_value = -1
-        mock_CrmMonXmlParser.return_value.is_resource_configured.return_value 
= False
-        mock_cluster_shell.return_value.get_stdout_or_raise_error.return_value 
= "data"
-        sbdmanager_instance = SBDManager()
-        sbdmanager_instance.configure_sbd()
-        
mock_cluster_shell.return_value.get_stdout_or_raise_error.assert_called_once_with("crm
 configure primitive stonith-sbd stonith:fence_sbd")
-
     @patch('crmsh.utils.cluster_run_cmd')
     @patch('crmsh.sbd.SBDTimeout.is_sbd_delay_start')
     @patch('crmsh.sbd.ServiceManager')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test/unittests/test_ui_sbd.py 
new/crmsh-5.0.0+20260226.8b99a4c5/test/unittests/test_ui_sbd.py
--- old/crmsh-5.0.0+20260209.ed56b53c/test/unittests/test_ui_sbd.py     
2026-02-09 08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test/unittests/test_ui_sbd.py     
2026-02-26 10:31:40.000000000 +0100
@@ -239,7 +239,7 @@
             res = self.sbd_instance_diskbased._configure_show(["xxx1", "xxx2"])
         self.assertEqual(str(e.exception), f"Unknown argument: xxx2")
 
-    @mock.patch('crmsh.sbd.SBDTimeoutChecker')
+    @mock.patch('crmsh.sbd.SBDConfigChecker')
     def test_configure_show_disk_metadata(self, mock_sbd_timeout_checker):
         mock_sbd_timeout_checker_instance = mock.Mock()
         mock_sbd_timeout_checker.return_value = 
mock_sbd_timeout_checker_instance
@@ -250,7 +250,7 @@
         mock_sbd_timeout_checker.assert_called_once_with()
         mock_sbd_timeout_checker_instance.check_and_fix.assert_called_once()
 
-    @mock.patch('crmsh.sbd.SBDTimeoutChecker')
+    @mock.patch('crmsh.sbd.SBDConfigChecker')
     @mock.patch('crmsh.ui_sbd.SBD._show_sysconfig')
     def test_configure_show_sysconfig(self, mock_show_sysconfig, 
mock_sbd_timeout_checker):
         mock_sbd_timeout_checker_instance = mock.Mock()
@@ -261,7 +261,7 @@
         mock_sbd_timeout_checker.assert_called_once_with()
         mock_sbd_timeout_checker_instance.check_and_fix.assert_called_once()
 
-    @mock.patch('crmsh.sbd.SBDTimeoutChecker')
+    @mock.patch('crmsh.sbd.SBDConfigChecker')
     def test_configure_show_property(self, mock_sbd_timeout_checker):
         mock_sbd_timeout_checker_instance = mock.Mock()
         mock_sbd_timeout_checker.return_value = 
mock_sbd_timeout_checker_instance
@@ -285,7 +285,7 @@
             self.assertIsNotNone(match)
             self.assertEqual(match.groups(), expected)
 
-    @mock.patch('crmsh.sbd.SBDTimeoutChecker')
+    @mock.patch('crmsh.sbd.SBDConfigChecker')
     @mock.patch('crmsh.ui_sbd.SBD._show_sysconfig')
     @mock.patch('builtins.print')
     def test_configure_show(self, mock_print, mock_show_sysconfig, 
mock_sbd_timeout_checker):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260209.ed56b53c/test_container/Dockerfile 
new/crmsh-5.0.0+20260226.8b99a4c5/test_container/Dockerfile
--- old/crmsh-5.0.0+20260209.ed56b53c/test_container/Dockerfile 2026-02-09 
08:58:33.000000000 +0100
+++ new/crmsh-5.0.0+20260226.8b99a4c5/test_container/Dockerfile 2026-02-26 
10:31:40.000000000 +0100
@@ -5,7 +5,7 @@
 
 RUN zypper -n dup && zypper -n install systemd openssh \
         firewalld iptables iptables-backend-nft \
-        make autoconf vim which libxslt-tools asciidoc mailx iproute2 iputils 
bzip2 tar file glibc-locale-base dos2unix cpio gawk sudo expect diffutils \
+        make autoconf vim which libxslt-tools asciidoc mailx iproute2 iputils 
bzip2 tar file glibc-locale-base cpio gawk sudo expect diffutils \
         python313 python313-pip python313-lxml python313-python-dateutil 
python313-build python313-PyYAML python313-curses python313-behave 
python313-coverage python313-packaging \
         csync2 corosync corosync-qdevice pacemaker pacemaker-remote booth 
corosync-qnetd
 

Reply via email to