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-04-02 17:44:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/crmsh (Old)
 and      /work/SRC/openSUSE:Factory/.crmsh.new.21863 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "crmsh"

Thu Apr  2 17:44:42 2026 rev:402 rq:1344335 version:5.0.0+20260402.90d08295

Changes:
--------
--- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes      2026-04-01 
19:53:34.484472853 +0200
+++ /work/SRC/openSUSE:Factory/.crmsh.new.21863/crmsh.changes   2026-04-02 
17:46:10.447708173 +0200
@@ -1,0 +2,26 @@
+Thu Apr 02 09:48:36 UTC 2026 - [email protected]
+
+- Update to version 5.0.0+20260402.90d08295:
+  * Dev: behave: Add functional test case for previous commit
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: sbd: And check and fix methods for fence_sbd pcmk_delay_max and 
crashdump parameter
+
+-------------------------------------------------------------------
+Thu Apr 02 09:04:04 UTC 2026 - [email protected]
+
+- Update to version 5.0.0+20260402.f2dfba7d:
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: bootstrap: Reject setup sbd stage if cluster is not quorate
+  * Dev: ui_sbd: Rename SBD.check_timeout_configurations to 
SBD.check_sbd_health
+  * Dev: sbd: Add diskless SBD warning while doing sbd health check
+
+-------------------------------------------------------------------
+Thu Apr 02 06:45:43 UTC 2026 - [email protected]
+
+- Update to version 5.0.0+20260402.66548890:
+  * Dev: unittests: Adjust unit test for previous commit
+  * Dev: behave: Adjust functional test for previous commit
+  * Dev: doc: Update the formular to calculate the expected 
fencing-watchdog-timeout
+  * Fix: sbd: Update the formular to calculate the expected 
fencing-watchdog-timeout
+
+-------------------------------------------------------------------

Old:
----
  crmsh-5.0.0+20260401.827507a4.tar.bz2

New:
----
  crmsh-5.0.0+20260402.90d08295.tar.bz2

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

Other differences:
------------------
++++++ crmsh.spec ++++++
--- /var/tmp/diff_new_pack.wQlYt6/_old  2026-04-02 17:46:11.515751950 +0200
+++ /var/tmp/diff_new_pack.wQlYt6/_new  2026-04-02 17:46:11.515751950 +0200
@@ -41,7 +41,7 @@
 Summary:        High Availability cluster command-line interface
 License:        GPL-2.0-or-later
 Group:          %{pkg_group}
-Version:        5.0.0+20260401.827507a4
+Version:        5.0.0+20260402.90d08295
 Release:        0
 URL:            http://crmsh.github.io
 Source0:        %{name}-%{version}.tar.bz2

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.wQlYt6/_old  2026-04-02 17:46:11.599755393 +0200
+++ /var/tmp/diff_new_pack.wQlYt6/_new  2026-04-02 17:46:11.635756868 +0200
@@ -9,7 +9,7 @@
 </service>
 <service name="tar_scm">
   <param name="url">https://github.com/ClusterLabs/crmsh.git</param>
-  <param 
name="changesrevision">e6dc4d82b19cba2e3d29ea342d57243cb08c82da</param>
+  <param 
name="changesrevision">0b408da8bf1caaf7e3471f62ff5f1a8f6aab41e3</param>
 </service>
 </servicedata>
 (No newline at EOF)

++++++ crmsh-5.0.0+20260401.827507a4.tar.bz2 -> 
crmsh-5.0.0+20260402.90d08295.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260401.827507a4/crmsh/bootstrap.py 
new/crmsh-5.0.0+20260402.90d08295/crmsh/bootstrap.py
--- old/crmsh-5.0.0+20260401.827507a4/crmsh/bootstrap.py        2026-04-01 
08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/crmsh/bootstrap.py        2026-04-02 
11:19:24.000000000 +0200
@@ -243,12 +243,11 @@
         with_sbd_option = self.sbd_devices or self.diskless_sbd
 
         if self.stage == "sbd":
-            if self.cluster_is_running:
-                utils.check_all_nodes_reachable("setup SBD")
-                node_list = utils.list_cluster_nodes()
-            else:
-                node_list = [utils.this_node()]
-            for node in node_list:
+            utils.check_all_nodes_reachable("setup SBD")
+            if not utils.calculate_quorate_status():
+                utils.fatal("Cluster is not quorate, can't run 'sbd' stage")
+
+            for node in utils.list_cluster_nodes():
                 if not utils.package_is_installed("sbd", node):
                     utils.fatal(sbd.SBDManager.SBD_NOT_INSTALLED_MSG + f" on 
{node}")
                 if self.sbd_devices and not 
utils.package_is_installed("fence-agents-sbd", node):
@@ -2791,14 +2790,11 @@
 
 def adjust_fencing_timeout():
     """
-    Adjust fencing-timeout for sbd and other scenarios
+    Adjust fencing-timeout for non sbd scenarios
     """
-    if ServiceManager().service_is_active(constants.SBD_SERVICE):
-        sbd.SBDConfigChecker(quiet=True, fix=True).check_and_fix()
-    else:
-        value = get_fencing_timeout_generally_expected()
-        if value:
-            utils.set_property("fencing-timeout", value, conditional=True)
+    value = get_fencing_timeout_generally_expected()
+    if value:
+        utils.set_property("fencing-timeout", value, conditional=True)
 
 
 def adjust_properties():
@@ -2815,14 +2811,17 @@
     - remove qdevice
     - add sbd via stage
     """
-    if not ServiceManager().service_is_active("pacemaker.service"):
+    service_manager = ServiceManager()
+    if not service_manager.service_is_active("pacemaker.service"):
         return
     is_2node_wo_qdevice = utils.is_2node_cluster_without_qdevice()
-    adjust_pcmk_delay_max(is_2node_wo_qdevice)
-    adjust_fencing_timeout()
+    if service_manager.service_is_active(constants.SBD_SERVICE):
+        sbd.SBDConfigChecker(quiet=True, fix=True).check_and_fix()
+    else:
+        adjust_pcmk_delay_max(is_2node_wo_qdevice)
+        adjust_fencing_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+20260401.827507a4/crmsh/sbd.py 
new/crmsh-5.0.0+20260402.90d08295/crmsh/sbd.py
--- old/crmsh-5.0.0+20260401.827507a4/crmsh/sbd.py      2026-04-01 
08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/crmsh/sbd.py      2026-04-02 
11:19:24.000000000 +0200
@@ -187,6 +187,22 @@
         value = utils.get_property("fencing-watchdog-timeout")
         return value and utils.crm_msec(value) > 0
 
+    @staticmethod
+    def get_fence_sbd_parameters() -> list[dict]:
+        configure_show_output = 
sh.cluster_shell().get_stdout_or_raise_error("crm configure show xml")
+        configure_show_in_xml = xmlutil.text2elem(configure_show_output)
+        ra_inst = cibquery.ResourceAgent("stonith", "", "fence_sbd")
+        res_id_list = cibquery.get_primitives_with_ra(configure_show_in_xml, 
ra_inst)
+
+        parameter_list = []
+        for res in res_id_list:
+            parameter_list.append({
+                "resource_id": res,
+                "crashdump": 
cibquery.get_parameter_value(configure_show_in_xml, res, "crashdump"),
+                "pcmk_delay_max": 
cibquery.get_parameter_value(configure_show_in_xml, res, "pcmk_delay_max"),
+            })
+        return parameter_list
+
 
 class SBDTimeout(object):
     '''
@@ -297,11 +313,14 @@
             raise ValueError("Cannot get the value of SBD_WATCHDOG_TIMEOUT")
         return int(res)
 
-    def get_fencing_watchdog_timeout_expected(self):
-        if self.crashdump_watchdog_timeout:
-            return SBDTimeout.get_sbd_watchdog_timeout() + 
self.crashdump_watchdog_timeout
-        else:
-            return 2 * SBDTimeout.get_sbd_watchdog_timeout()
+    @staticmethod
+    def get_fencing_watchdog_timeout_expected(
+            crashdump_watchdog_timeout: int|None = None,
+            sbd_watchdog_timeout: int|None = None
+        ):
+        cwt = crashdump_watchdog_timeout or 
SBDUtils.get_crashdump_watchdog_timeout()
+        swt = sbd_watchdog_timeout or SBDTimeout.get_sbd_watchdog_timeout()
+        return max(swt+cwt, 2*swt) if cwt else 2 * swt
 
     def _load_configurations_from_runtime(self):
         '''
@@ -317,10 +336,11 @@
             self.sbd_msgwait = device_metadata.get("msgwait")
             self.sbd_watchdog_timeout = device_metadata.get("watchdog")
             self.pcmk_delay_max = 
utils.get_pcmk_delay_max(self.two_node_without_qdevice)
+            self.fence_sbd_parameters = SBDUtils.get_fence_sbd_parameters()
         else:  # disk-less
             self.disk_based = False
             self.sbd_watchdog_timeout = SBDTimeout.get_sbd_watchdog_timeout()
-            self.fencing_watchdog_timeout = 
self.get_fencing_watchdog_timeout_expected()
+            self.fencing_watchdog_timeout = 
SBDTimeout.get_fencing_watchdog_timeout_expected()
         self.sbd_delay_start_value_expected = 
self.get_sbd_delay_start_expected() if utils.detect_virt() else "no"
         self.sbd_delay_start_value_from_config = 
SBDUtils.get_sbd_value_from_config("SBD_DELAY_START")
         if not self.sbd_delay_start_value_from_config:
@@ -487,6 +507,7 @@
     SBD_DEVICE_METADATA_CONSISTENCY = auto()
     SBD_WATCHDOG_TIMEOUT = auto()
     FENCE_SBD_AGENT = auto()
+    FENCE_SBD_AGENT_PARAMETERS = auto()
     SBD_DELAY_START = auto()
     SBD_SYSTEMD_START_TIMEOUT = auto()
     FENCING_WATCHDOG_TIMEOUT_PROPERTY = auto()
@@ -566,6 +587,14 @@
             ),
 
             (
+                "fence_sbd agent parameters",
+                self._check_fence_sbd_parameters,
+                self._fix_fence_sbd_parameters,
+                False,
+                [SBDCheckItem.FENCE_SBD_AGENT]
+            ),
+
+            (
                 "SBD_DELAY_START",
                 self._check_sbd_delay_start,
                 self._fix_sbd_delay_start,
@@ -573,7 +602,7 @@
                 [
                     SBDCheckItem.SBD_DISK_METADATA,
                     SBDCheckItem.SBD_WATCHDOG_TIMEOUT,
-                    SBDCheckItem.FENCE_SBD_AGENT
+                    SBDCheckItem.FENCE_SBD_AGENT_PARAMETERS
                 ]
             ),
 
@@ -682,6 +711,7 @@
                     raise FixFailure(f"Failed to fix {name} issue")
 
         SBDConfigChecker._check_deprecated_property()
+        SBDManager.warn_diskless_sbd()
 
         return SBDConfigChecker._return_helper(check_res_list)
 
@@ -988,6 +1018,7 @@
     def _check_fence_sbd(self) -> CheckResult:
         if not self.disk_based:
             return CheckResult.SUCCESS
+
         xml_inst = xmlutil.CrmMonXmlParser()
         if xml_inst.not_connected():
             cib = 
xmlutil.text2elem(sh.cluster_shell().get_stdout_or_raise_error("crm configure 
show xml"))
@@ -1016,6 +1047,7 @@
                 SBDManager.SBD_RA
             )
             return CheckResult.ERROR
+
         return CheckResult.SUCCESS
 
     def _fix_fence_sbd(self):
@@ -1025,8 +1057,9 @@
             logger.info("Configuring fence agent %s", SBDManager.SBD_RA)
             cmd = f"crm configure primitive {SBDManager.SBD_RA_ID} 
{SBDManager.SBD_RA}"
             shell.get_stdout_or_raise_error(cmd)
-            is_2node_wo_qdevice = utils.is_2node_cluster_without_qdevice()
-            bootstrap.adjust_pcmk_delay_max(is_2node_wo_qdevice)
+            if self.two_node_without_qdevice:
+                cmd = f"crm resource param {SBDManager.SBD_RA_ID} set 
pcmk_delay_max {constants.PCMK_DELAY_MAX}s"
+                shell.get_stdout_or_raise_error(cmd)
         elif not xml_inst.is_resource_started(SBDManager.SBD_RA):
             res_id_list = 
xml_inst.get_resource_id_list_via_type(SBDManager.SBD_RA)
             for res_id in res_id_list:
@@ -1044,6 +1077,77 @@
         ):
             utils.DeprecatedTermTranslator(prop).check()
 
+    def _check_fence_sbd_parameters(self) -> CheckResult:
+        if not self.disk_based:
+            return CheckResult.SUCCESS
+        if not self.fence_sbd_parameters:
+            self._log_when_not_quiet(
+                logging.ERROR,
+                "Fence agent %s is not configured",
+                SBDManager.SBD_RA
+            )
+            return CheckResult.ERROR
+
+        result_list = []
+        for fence_sbd_param in self.fence_sbd_parameters:
+            res_id, crashdump, pcmk_delay_max = fence_sbd_param.values()
+            if utils.is_boolean_false(crashdump) and 
self.crashdump_watchdog_timeout:
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "It's required that crashdump parameter is set to '1' in 
resource %s when sbd crashdump is configured, now is not set",
+                    res_id
+                )
+                result_list.append(CheckResult.ERROR)
+            elif utils.is_boolean_true(crashdump) and not 
self.crashdump_watchdog_timeout:
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "It's recommended that crashdump parameter should not be 
set in resource %s when sbd crashdump is not configured",
+                    res_id
+                )
+                result_list.append(CheckResult.WARNING)
+
+            if self.two_node_without_qdevice and not pcmk_delay_max:
+                self._log_when_not_quiet(
+                    logging.ERROR,
+                    "It's required that pcmk_delay_max parameter is set to %ds 
in resource %s for 2-node cluster without qdevice, now is not set",
+                    constants.PCMK_DELAY_MAX, res_id
+                )
+                result_list.append(CheckResult.ERROR)
+            elif pcmk_delay_max and not self.two_node_without_qdevice:
+                self._log_when_not_quiet(
+                    logging.WARNING,
+                    "It's recommended that pcmk_delay_max parameter should not 
be set in resource %s for clusters other than 2-node cluster without qdevice",
+                    res_id
+                )
+                result_list.append(CheckResult.WARNING)
+
+        return SBDConfigChecker._return_helper(result_list)
+
+    def _fix_fence_sbd_parameters(self):
+        shell = sh.cluster_shell()
+        for fence_sbd_param in self.fence_sbd_parameters:
+            cmd_for_crashdump, cmd_for_pcmk_delay_max = None, None
+            res_id, crashdump, pcmk_delay_max = fence_sbd_param.values()
+
+            if utils.is_boolean_false(crashdump) and 
self.crashdump_watchdog_timeout:
+                logger.info("Setting crashdump parameter to '1' in resource 
%s", res_id)
+                cmd_for_crashdump = f"crm resource param {res_id} set 
crashdump 1"
+            elif utils.is_boolean_true(crashdump) and not 
self.crashdump_watchdog_timeout:
+                logger.info("Removing crashdump parameter in resource %s", 
res_id)
+                cmd_for_crashdump = f"crm resource param {res_id} delete 
crashdump"
+            if cmd_for_crashdump:
+                shell.get_stdout_or_raise_error(cmd_for_crashdump)
+
+            if self.two_node_without_qdevice and not pcmk_delay_max:
+                logger.info("Setting pcmk_delay_max parameter to %ds in 
resource %s", constants.PCMK_DELAY_MAX, res_id)
+                cmd_for_pcmk_delay_max = f"crm resource param {res_id} set 
pcmk_delay_max {constants.PCMK_DELAY_MAX}s"
+            elif pcmk_delay_max and not self.two_node_without_qdevice:
+                logger.info("Removing pcmk_delay_max parameter in resource 
%s", res_id)
+                cmd_for_pcmk_delay_max = f"crm resource param {res_id} delete 
pcmk_delay_max"
+            if cmd_for_pcmk_delay_max:
+                shell.get_stdout_or_raise_error(cmd_for_pcmk_delay_max)
+
+
 class SBDManager:
     SYSCONFIG_SBD = "/etc/sysconfig/sbd"
     SYSCONFIG_SBD_TEMPLATE = "/usr/share/fillup-templates/sysconfig.sbd"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260401.827507a4/crmsh/ui_sbd.py 
new/crmsh-5.0.0+20260402.90d08295/crmsh/ui_sbd.py
--- old/crmsh-5.0.0+20260401.827507a4/crmsh/ui_sbd.py   2026-04-01 
08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/crmsh/ui_sbd.py   2026-04-02 
11:19:24.000000000 +0200
@@ -256,10 +256,10 @@
             self._show_property()
 
         print()
-        return SBD.check_timeout_configurations()
+        return SBD.check_sbd_health()
 
     @staticmethod
-    def check_timeout_configurations() -> bool:
+    def check_sbd_health() -> bool:
         check_rc = sbd.CheckResult.SUCCESS
         try:
             check_rc = sbd.SBDConfigChecker().check_and_fix()
@@ -459,7 +459,6 @@
         Configure diskless SBD based on input parameters and runtime config
         '''
         update_dict = {}
-        timeout_dict = {}
 
         watchdog_timeout = parameter_dict.get("watchdog")
         if watchdog_timeout and watchdog_timeout != 
self.watchdog_timeout_from_config:
@@ -473,23 +472,21 @@
             self._check_kdump_service()
             result_dict = 
self._set_crashdump_in_sysconfig(crashdump_watchdog_timeout, diskless=True)
             update_dict = {**update_dict, **result_dict}
-            sbd_watchdog_timeout = watchdog_timeout or 
self.watchdog_timeout_from_config
-            fencing_watchdog_timeout = sbd_watchdog_timeout + 
crashdump_watchdog_timeout
-            logger.info("Set fencing-watchdog-timeout to SBD_WATCHDOG_TIMEOUT 
+ crashdump-watchdog-timeout: %s", fencing_watchdog_timeout)
-            timeout_dict["fencing-watchdog"] = fencing_watchdog_timeout
         if not update_dict:
             logger.info("No change in SBD configuration")
             return
 
         restart_first = False
         if watchdog_timeout:
-            expected_fencing_watchdog_timeout = 
timeout_dict.get("fencing-watchdog", 2*watchdog_timeout)
+            expected_fencing_watchdog_timeout = 
sbd.SBDTimeout.get_fencing_watchdog_timeout_expected(
+                crashdump_watchdog_timeout,
+                watchdog_timeout
+            )
             # If the expected fencing-watchdog-timeout is smaller than runtime 
SBD_WATCHDOG_TIMEOUT, restart cluster first
             if expected_fencing_watchdog_timeout < 
self.watchdog_timeout_from_config:
                 restart_first = True
 
         sbd_manager = sbd.SBDManager(
-            timeout_dict=timeout_dict,
             update_dict=update_dict,
             diskless_sbd=True
         )
@@ -745,4 +742,4 @@
         self._print_sbd_cgroup_status()
         self._print_watchdog_info()
         self._print_sbd_agent_status()
-        return SBD.check_timeout_configurations()
+        return SBD.check_sbd_health()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260401.827507a4/crmsh/utils.py 
new/crmsh-5.0.0+20260402.90d08295/crmsh/utils.py
--- old/crmsh-5.0.0+20260401.827507a4/crmsh/utils.py    2026-04-01 
08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/crmsh/utils.py    2026-04-02 
11:19:24.000000000 +0200
@@ -2460,10 +2460,14 @@
     return reachable_node_list
 
 
-def calculate_quorate_status(expected_votes, actual_votes):
+def calculate_quorate_status(expected_votes=-1, actual_votes=-1):
     """
     Given expected votes and actual votes, calculate if is quorated
     """
+    if expected_votes <= 0 or actual_votes < 0:
+        quorum_votes_dict = get_quorum_votes_dict()
+        expected_votes = quorum_votes_dict.get("Expected")
+        actual_votes = quorum_votes_dict.get("Total")
     return int(actual_votes)/int(expected_votes) > 0.5
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/crmsh-5.0.0+20260401.827507a4/doc/crm.8.adoc 
new/crmsh-5.0.0+20260402.90d08295/doc/crm.8.adoc
--- old/crmsh-5.0.0+20260401.827507a4/doc/crm.8.adoc    2026-04-01 
08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/doc/crm.8.adoc    2026-04-02 
11:19:24.000000000 +0200
@@ -354,7 +354,7 @@
     fencing-watchdog-timeout = 2 * SBD_WATCHDOG_TIMEOUT
 
     # When setting crashdump watchdog timeout
-    fencing-watchdog-timeout = SBD_WATCHDOG_TIMEOUT + 
crashdump_watchdog_timeout
+    fencing-watchdog-timeout = max(SBD_WATCHDOG_TIMEOUT + 
crashdump_watchdog_timeout, 2 * SBD_WATCHDOG_TIMEOUT)
 ...............
 `fencing-timeout`:
 ...............
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260401.827507a4/test/features/bootstrap_sbd_delay.feature 
new/crmsh-5.0.0+20260402.90d08295/test/features/bootstrap_sbd_delay.feature
--- old/crmsh-5.0.0+20260401.827507a4/test/features/bootstrap_sbd_delay.feature 
2026-04-01 08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/test/features/bootstrap_sbd_delay.feature 
2026-04-02 11:19:24.000000000 +0200
@@ -369,6 +369,17 @@
     Then    Expected "It's required that fencing-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
+    # check crashdump and pcmk_delay_max
+    When    Run "crm resource param fencing-sbd set crashdump 1" on "hanode1"
+    When    Run "crm resource param fencing-sbd delete pcmk_delay_max" on 
"hanode1"
+    When    Try "crm cluster health sbd" on "hanode1"
+    Then    Expected multiple lines in stderr
+      """
+      It's recommended that crashdump parameter should not be set in resource 
fencing-sbd when sbd crashdump is not configured
+      It's required that pcmk_delay_max parameter is set to 30s in resource 
fencing-sbd for 2-node cluster without qdevice, now is not set
+      """
+    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
     When    Run "sed -i 's/token: .*/token: 10000/' 
/etc/corosync/corosync.conf" on "hanode1"
     When    Run "sed -i 's/token: .*/token: 10000/' 
/etc/corosync/corosync.conf" on "hanode2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260401.827507a4/test/features/sbd_ui.feature 
new/crmsh-5.0.0+20260402.90d08295/test/features/sbd_ui.feature
--- old/crmsh-5.0.0+20260401.827507a4/test/features/sbd_ui.feature      
2026-04-01 08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/test/features/sbd_ui.feature      
2026-04-02 11:19:24.000000000 +0200
@@ -121,6 +121,8 @@
     Then    Run "crm sbd configure show property |grep 
fencing-watchdog-timeout=75" OK
     When    Run "crm sbd configure crashdump-watchdog-timeout=60" on "hanode1"
     Then    Expected "No change in SBD configuration" in stdout
+    When    Run "crm sbd configure crashdump-watchdog-timeout=10" on "hanode1"
+    Then    Run "crm sbd configure show property |grep 
fencing-watchdog-timeout=30" OK
     # Purge crashdump
     When    Run "crm sbd purge crashdump" on "hanode1"
     When    Try "crm sbd configure show sysconfig |grep 
SBD_TIMEOUT_ACTION=flush,crashdump"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260401.827507a4/test/unittests/test_bootstrap.py 
new/crmsh-5.0.0+20260402.90d08295/test/unittests/test_bootstrap.py
--- old/crmsh-5.0.0+20260401.827507a4/test/unittests/test_bootstrap.py  
2026-04-01 08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/test/unittests/test_bootstrap.py  
2026-04-02 11:19:24.000000000 +0200
@@ -139,9 +139,14 @@
             ctx._validate_sbd_option()
         mock_error.assert_called_once_with("Can't use -s and -S options 
together")
 
+    @mock.patch('crmsh.utils.list_cluster_nodes')
+    @mock.patch('crmsh.utils.check_all_nodes_reachable')
+    @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.package_is_installed')
     @mock.patch('crmsh.utils.fatal')
-    def test_validate_sbd_option_error_sbd_stage_no_option(self, mock_error, 
mock_installed):
+    def test_validate_sbd_option_error_sbd_stage_no_option(self, mock_error, 
mock_installed, mock_quorate, mock_check_all, mock_list):
+        mock_list.return_value = ["node1"]
+        mock_quorate.return_value = True
         mock_installed.return_value = True
         mock_error.side_effect = SystemExit
         ctx = crmsh.bootstrap.Context()
@@ -151,10 +156,15 @@
             ctx._validate_sbd_option()
         mock_error.assert_called_once_with("Stage sbd should specify sbd 
device by -s or diskless sbd by -S option")
 
+    @mock.patch('crmsh.utils.list_cluster_nodes')
+    @mock.patch('crmsh.utils.check_all_nodes_reachable')
+    @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.package_is_installed')
     @mock.patch('crmsh.utils.fatal')
     @mock.patch('crmsh.service_manager.ServiceManager.service_is_active')
-    def test_validate_sbd_option_error_sbd_stage_service(self, mock_active, 
mock_error, mock_installed):
+    def test_validate_sbd_option_error_sbd_stage_service(self, mock_active, 
mock_error, mock_installed, mock_quorate, mock_check_all, mock_list):
+        mock_list.return_value = ["node1"]
+        mock_quorate.return_value = True
         mock_installed.return_value = True
         mock_error.side_effect = SystemExit
         ctx = crmsh.bootstrap.Context()
@@ -166,18 +176,19 @@
         mock_error.assert_called_once_with("Can't configure stage sbd: 
sbd.service already running! Please use crm option '-F' if need to redeploy")
         mock_active.assert_called_once_with("sbd.service")
 
+    @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.fatal')
     @mock.patch('crmsh.utils.list_cluster_nodes')
     @mock.patch('crmsh.utils.package_is_installed')
     @mock.patch('crmsh.utils.check_all_nodes_reachable')
-    def test_validate_sbd_option_error_sbd_stage(self, mock_check_all, 
mock_installed, mock_list, mock_fatal):
+    def test_validate_sbd_option_error_sbd_stage(self, mock_check_all, 
mock_installed, mock_list, mock_fatal, mock_quorate):
+        mock_quorate.return_value = True
         mock_fatal.side_effect = ValueError
         mock_list.return_value = ["node1", "node2"]
         mock_installed.side_effect = [True, False]
         ctx = crmsh.bootstrap.Context()
         ctx.stage = "sbd"
         ctx.diskless_sbd = True
-        ctx.cluster_is_running = True
         with self.assertRaises(ValueError):
             ctx._validate_sbd_option()
         mock_check_all.assert_called_once_with("setup SBD")
@@ -186,18 +197,19 @@
             mock.call("sbd", "node2")
         ])
 
+    @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.fatal')
     @mock.patch('crmsh.utils.package_is_installed')
     @mock.patch('crmsh.utils.list_cluster_nodes')
     @mock.patch('crmsh.utils.check_all_nodes_reachable')
-    def test_validate_sbd_option_sbd_package_not_installed(self, 
mock_check_all, mock_list, mock_installed, mock_fatal):
+    def test_validate_sbd_option_sbd_package_not_installed(self, 
mock_check_all, mock_list, mock_installed, mock_fatal, mock_quorate):
+        mock_quorate.return_value = True
         mock_fatal.side_effect = ValueError
         mock_list.return_value = ["node1", "node2"]
         mock_installed.return_value = False
         ctx = crmsh.bootstrap.Context()
         ctx.stage = "sbd"
         ctx.diskless_sbd = True
-        ctx.cluster_is_running = True
 
         with self.assertRaises(ValueError):
             ctx._validate_sbd_option()
@@ -206,13 +218,16 @@
         mock_installed.assert_called_once_with("sbd", "node1")
         
mock_fatal.assert_called_once_with(sbd.SBDManager.SBD_NOT_INSTALLED_MSG + " on 
node1")
 
+    @mock.patch('crmsh.utils.list_cluster_nodes')
+    @mock.patch('crmsh.utils.check_all_nodes_reachable')
+    @mock.patch('crmsh.utils.calculate_quorate_status')
     @mock.patch('crmsh.utils.fatal')
     @mock.patch('crmsh.utils.package_is_installed')
-    @mock.patch('crmsh.utils.this_node')
     @mock.patch('crmsh.sbd.SBDUtils.verify_sbd_device')
-    def test_validate_sbd_option_fence_sbd_package_not_installed(self, 
mock_verify, mock_this_node, mock_installed, mock_fatal):
+    def test_validate_sbd_option_fence_sbd_package_not_installed(self, 
mock_verify, mock_installed, mock_fatal, mock_quorate, mock_check_all, 
mock_list):
+        mock_quorate.return_value = True
+        mock_list.return_value = ["node1"]
         mock_fatal.side_effect = ValueError
-        mock_this_node.return_value = "node1"
         mock_installed.side_effect = [True, False]
         ctx = crmsh.bootstrap.Context()
         ctx.sbd_devices = ["/dev/sda1"]
@@ -1478,21 +1493,9 @@
         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.SBDConfigChecker')
-    @mock.patch('crmsh.service_manager.ServiceManager.service_is_active')
-    def test_adjust_fencing_timeout_sbd(self, mock_is_active, 
mock_sbd_checker):
-        mock_sbd_checker_inst = mock.Mock()
-        mock_sbd_checker.return_value = mock_sbd_checker_inst
-        mock_sbd_checker_inst.check_and_fix = mock.Mock()
-        mock_is_active.return_value = True
-        bootstrap.adjust_fencing_timeout()
-        mock_sbd_checker.assert_called_once_with(quiet=True, fix=True)
-
     @mock.patch('crmsh.utils.set_property')
     @mock.patch('crmsh.bootstrap.get_fencing_timeout_generally_expected')
-    @mock.patch('crmsh.service_manager.ServiceManager.service_is_active')
-    def test_adjust_fencing_timeout(self, mock_is_active, mock_get_timeout, 
mock_set):
-        mock_is_active.return_value = False
+    def test_adjust_fencing_timeout(self, mock_get_timeout, mock_set):
         mock_get_timeout.return_value = 30
         bootstrap.adjust_fencing_timeout()
         mock_set.assert_called_once_with("fencing-timeout", 30, 
conditional=True)
@@ -1527,23 +1530,24 @@
         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_fencing_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_fencing, mock_adj_priority, mock_adj_fence, 
mock_warn_sbd):
-        mock_is_active.return_value = True
+    def test_adjust_properties(self, mock_is_active, mock_2node_qdevice, 
mock_adj_pcmk, mock_adj_fencing, mock_adj_priority, mock_adj_fence):
+        mock_is_active.side_effect = [True, False]
         mock_2node_qdevice.return_value = True
         bootstrap.adjust_properties()
-        mock_is_active.assert_called_once_with("pacemaker.service")
+        mock_is_active.assert_has_calls([
+            mock.call("pacemaker.service"),
+            mock.call("sbd.service")
+        ])
         mock_adj_pcmk.assert_called_once_with(True)
         mock_adj_fencing.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+20260401.827507a4/test/unittests/test_sbd.py 
new/crmsh-5.0.0+20260402.90d08295/test/unittests/test_sbd.py
--- old/crmsh-5.0.0+20260401.827507a4/test/unittests/test_sbd.py        
2026-04-01 08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/test/unittests/test_sbd.py        
2026-04-02 11:19:24.000000000 +0200
@@ -335,10 +335,11 @@
         self.instance_check._check_config_consistency.assert_called_once()
 
     @patch('crmsh.sbd.SBDConfigChecker._check_deprecated_property')
+    @patch('crmsh.sbd.SBDManager.warn_diskless_sbd')
     @patch('crmsh.utils.list_cluster_nodes_except_me')
     @patch('crmsh.utils.check_all_nodes_reachable')
     @patch('crmsh.sbd.ServiceManager')
-    def test_check_and_fix_not_fix(self, mock_service_manager, 
mock_check_all_nodes_reachable, mock_list_cluster_nodes_except_me, 
mock_check_deprecated_property):
+    def test_check_and_fix_not_fix(self, mock_service_manager, 
mock_check_all_nodes_reachable, mock_list_cluster_nodes_except_me, 
mock_warn_diskless_sbd, mock_check_deprecated_property):
         mock_service_manager_inst = Mock()
         mock_service_manager.return_value = mock_service_manager_inst
         mock_service_manager_inst.service_is_active = Mock(return_value=True)
@@ -385,10 +386,11 @@
         self.assertTrue("Failed to fix SBD disk metadata" in 
str(context.exception))
 
     @patch('crmsh.sbd.SBDConfigChecker._check_deprecated_property')
+    @patch('crmsh.sbd.SBDManager.warn_diskless_sbd')
     @patch('crmsh.utils.list_cluster_nodes_except_me')
     @patch('crmsh.utils.check_all_nodes_reachable')
     @patch('crmsh.sbd.ServiceManager')
-    def test_check_and_fix_fix_success(self, mock_service_manager, 
mock_check_all_nodes_reachable, mock_list_cluster_nodes_except_me, 
mock_check_deprecated_property):
+    def test_check_and_fix_fix_success(self, mock_service_manager, 
mock_check_all_nodes_reachable, mock_list_cluster_nodes_except_me, 
mock_warn_diskless_sbd, mock_check_deprecated_property):
         mock_service_manager_inst = Mock()
         mock_service_manager.return_value = mock_service_manager_inst
         mock_service_manager_inst.service_is_active = Mock(return_value=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/crmsh-5.0.0+20260401.827507a4/test/unittests/test_ui_sbd.py 
new/crmsh-5.0.0+20260402.90d08295/test/unittests/test_ui_sbd.py
--- old/crmsh-5.0.0+20260401.827507a4/test/unittests/test_ui_sbd.py     
2026-04-01 08:32:17.000000000 +0200
+++ new/crmsh-5.0.0+20260402.90d08295/test/unittests/test_ui_sbd.py     
2026-04-02 11:19:24.000000000 +0200
@@ -452,7 +452,6 @@
         mock_SBDManager.return_value.init_and_deploy_sbd = mock.Mock()
         self.sbd_instance_diskless._configure_diskless(parameter_dict)
         mock_SBDManager.assert_called_once_with(
-            timeout_dict={'fencing-watchdog': 24},
             update_dict={'SBD_WATCHDOG_TIMEOUT': '12', 'SBD_WATCHDOG_DEV': 
'/dev/watchdog100', 'SBD_TIMEOUT_ACTION': 'flush,crashdump', 'SBD_OPTS': '-C 12 
-Z'},
             diskless_sbd=True
         )
@@ -716,7 +715,7 @@
         
self.sbd_instance_diskbased.cluster_shell.get_stdout_or_raise_error.side_effect 
= [data_node1, "10", data_node2, "10"]
         self.sbd_instance_diskbased._print_watchdog_info()
 
-    @mock.patch('crmsh.ui_sbd.SBD.check_timeout_configurations')
+    @mock.patch('crmsh.ui_sbd.SBD.check_sbd_health')
     def test_do_status(self, mock_check_timeout):
         self.sbd_instance_diskbased._load_attributes = mock.Mock()
         self.sbd_instance_diskbased._print_sbd_type = mock.Mock()

Reply via email to