Hello community, here is the log from the commit of package crmsh for openSUSE:Factory checked in at 2020-08-25 09:32:32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/crmsh (Old) and /work/SRC/openSUSE:Factory/.crmsh.new.3399 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "crmsh" Tue Aug 25 09:32:32 2020 rev:190 rq:828895 version:4.2.0+git.1598257562.570eb99d Changes: -------- --- /work/SRC/openSUSE:Factory/crmsh/crmsh.changes 2020-08-04 20:24:14.117019079 +0200 +++ /work/SRC/openSUSE:Factory/.crmsh.new.3399/crmsh.changes 2020-08-25 09:34:05.556047477 +0200 @@ -1,0 +2,9 @@ +Mon Aug 24 08:38:32 UTC 2020 - [email protected] + +- Update to version 4.2.0+git.1598257562.570eb99d: + * Fix: bootstrap: revert ssh_merge function for compatibility(bsc#1175057) + * Dev: behave: adjust functional test for sbd config process changes + * Dev: unittest: adjust unit test cases for sbd config process changes + * Fix: bootstrap: adjust sbd config process to fix bug on sbd stage(bsc#1175057) + +------------------------------------------------------------------- Old: ---- crmsh-4.2.0+git.1595940615.c452cc00.tar.bz2 New: ---- crmsh-4.2.0+git.1598257562.570eb99d.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ crmsh.spec ++++++ --- /var/tmp/diff_new_pack.eodrrj/_old 2020-08-25 09:34:09.956050044 +0200 +++ /var/tmp/diff_new_pack.eodrrj/_new 2020-08-25 09:34:09.960050047 +0200 @@ -36,7 +36,7 @@ Summary: High Availability cluster command-line interface License: GPL-2.0-or-later Group: %{pkg_group} -Version: 4.2.0+git.1595940615.c452cc00 +Version: 4.2.0+git.1598257562.570eb99d Release: 0 Url: http://crmsh.github.io Source0: %{name}-%{version}.tar.bz2 ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.eodrrj/_old 2020-08-25 09:34:09.992050065 +0200 +++ /var/tmp/diff_new_pack.eodrrj/_new 2020-08-25 09:34:09.992050065 +0200 @@ -5,4 +5,4 @@ <param name="url">https://github.com/liangxin1300/crmsh.git</param> <param name="changesrevision">d8dc51b4cb34964aa72e918999ebc7f03b48f3c9</param></service><service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/crmsh.git</param> - <param name="changesrevision">5350f49f9e5990568c2626a6b02446dcbfbca340</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">d4e0b8e57815925f3d625bcfda0d538ca69c1e91</param></service></servicedata> \ No newline at end of file ++++++ crmsh-4.2.0+git.1595940615.c452cc00.tar.bz2 -> crmsh-4.2.0+git.1598257562.570eb99d.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.2.0+git.1595940615.c452cc00/crmsh/bootstrap.py new/crmsh-4.2.0+git.1598257562.570eb99d/crmsh/bootstrap.py --- old/crmsh-4.2.0+git.1595940615.c452cc00/crmsh/bootstrap.py 2020-07-28 14:50:15.000000000 +0200 +++ new/crmsh-4.2.0+git.1598257562.570eb99d/crmsh/bootstrap.py 2020-08-24 10:26:02.000000000 +0200 @@ -166,7 +166,6 @@ """ self.sbd_devices_input = sbd_devices self.diskless_sbd = diskless_sbd - self._sbd_service_flag = False self._sbd_devices = None @staticmethod @@ -309,35 +308,27 @@ """ self._get_sbd_device() if not self._sbd_devices and not self.diskless_sbd: + invoke("systemctl disable sbd.service") return status_long("Initializing {}SBD...".format("diskless " if self.diskless_sbd else "")) self._initialize_sbd() self._update_configuration() + invoke("systemctl enable sbd.service") status_done() - # If process work through here, consider it's ready for enable service - self._sbd_service_flag = True - - def manage_sbd_service(self): - """ - Manage sbd service, running on both init and join process - """ - if self._sbd_service_flag: - invoke("systemctl enable sbd.service") - else: - invoke("systemctl disable sbd.service") def configure_sbd_resource(self): """ Configure stonith-sbd resource and stonith-enabled property """ - if self._sbd_devices and self._get_sbd_device_from_config(): - if not invoke("crm configure primitive stonith-sbd stonith:external/sbd pcmk_delay_max=30s"): - error("Can't create stonith-sbd primitive") - if not invoke("crm configure property stonith-enabled=true"): - error("Can't enable STONITH for SBD") - elif self.diskless_sbd: - if not invoke("crm configure property stonith-enabled=true stonith-watchdog-timeout=5s"): - error("Can't enable STONITH for diskless SBD") + if service_is_enabled("sbd.service"): + if self._get_sbd_device_from_config(): + if not invoke("crm configure primitive stonith-sbd stonith:external/sbd pcmk_delay_max=30s"): + error("Can't create stonith-sbd primitive") + if not invoke("crm configure property stonith-enabled=true"): + error("Can't enable STONITH for SBD") + else: + if not invoke("crm configure property stonith-enabled=true stonith-watchdog-timeout=5s"): + error("Can't enable STONITH for diskless SBD") def join_sbd(self, peer_host): """ @@ -345,16 +336,16 @@ On joining process, check whether peer node has enabled sbd.service If so, check prerequisites of SBD and verify sbd device on join node """ - if not os.path.exists(SYSCONFIG_SBD): - return - if not invoke("ssh -o StrictHostKeyChecking=no root@{} systemctl is-enabled sbd.service".format(peer_host)): + cmd_detect_enabled = "ssh -o StrictHostKeyChecking=no root@{} systemctl is-enabled sbd.service".format(peer_host) + if not os.path.exists(SYSCONFIG_SBD) or not invoke(cmd_detect_enabled): + invoke("systemctl disable sbd.service") return self._check_environment() dev_list = self._get_sbd_device_from_config() if dev_list: self._verify_sbd_device(dev_list) status("Got {}SBD configuration".format("" if dev_list else "diskless ")) - self._sbd_service_flag = True + invoke("systemctl enable sbd.service") _context = None @@ -943,8 +934,6 @@ if pass_msg: warn("You should change the hacluster password to something more secure!") - _context.sbd_manager.manage_sbd_service() - start_service("pacemaker.service") wait_for_cluster() @@ -1876,6 +1865,48 @@ status_done() +def join_ssh_merge(_cluster_node): + status("Merging known_hosts") + + me = utils.this_node() + hosts = [m.group(1) + for m in re.finditer(r"^\s*host\s*([^ ;]+)\s*;", open(CSYNC2_CFG).read(), re.M) + if m.group(1) != me] + if not hosts: + hosts = [_cluster_node] + warn("Unable to extract host list from %s" % (CSYNC2_CFG)) + + try: + import parallax + except ImportError: + error("parallax python library is missing") + + opts = parallax.Options() + opts.ssh_options = ['StrictHostKeyChecking=no'] + + # The act of using pssh to connect to every host (without strict host key + # checking) ensures that at least *this* host has every other host in its + # known_hosts + known_hosts_new = set() + cat_cmd = "[ -e /root/.ssh/known_hosts ] && cat /root/.ssh/known_hosts || true" + log("parallax.call {} : {}".format(hosts, cat_cmd)) + results = parallax.call(hosts, cat_cmd, opts) + for host, result in results.items(): + if isinstance(result, parallax.Error): + warn("Failed to get known_hosts from {}: {}".format(host, str(result))) + else: + if result[1]: + known_hosts_new.update((utils.to_ascii(result[1]) or "").splitlines()) + if known_hosts_new: + hoststxt = "\n".join(sorted(known_hosts_new)) + tmpf = utils.str2tmp(hoststxt) + log("parallax.copy {} : {}".format(hosts, hoststxt)) + results = parallax.copy(hosts, tmpf, "/root/.ssh/known_hosts") + for host, result in results.items(): + if isinstance(result, parallax.Error): + warn("scp to {} failed ({}), known_hosts update may be incomplete".format(host, str(result))) + + def update_expected_votes(): # get a list of nodes, excluding remote nodes nodelist = None @@ -2421,6 +2452,7 @@ join_ssh(cluster_node) join_remote_auth(cluster_node) join_csync2(cluster_node) + join_ssh_merge(cluster_node) join_cluster(cluster_node) status("Done (log saved to %s)" % (LOG_FILE)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.2.0+git.1595940615.c452cc00/test/features/bootstrap_sbd.feature new/crmsh-4.2.0+git.1598257562.570eb99d/test/features/bootstrap_sbd.feature --- old/crmsh-4.2.0+git.1595940615.c452cc00/test/features/bootstrap_sbd.feature 2020-07-28 14:50:15.000000000 +0200 +++ new/crmsh-4.2.0+git.1598257562.570eb99d/test/features/bootstrap_sbd.feature 2020-08-24 10:26:02.000000000 +0200 @@ -77,3 +77,41 @@ When Run "crm cluster join -c hanode1 -y" on "hanode2" Then Cluster service is "started" on "hanode2" And Service "sbd" is "started" on "hanode2" + + @clean + Scenario: Configure sbd in several stages(bsc#1175057) + Given Cluster service is "stopped" on "hanode1" + Given Cluster service is "stopped" on "hanode2" + When Run "crm cluster init ssh -y" on "hanode1" + And Run "crm cluster init csync2 -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" + 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" + And Run "crm cluster join csync2 -y -c hanode1" on "hanode2" + And Run "crm cluster join ssh_merge -y -c hanode1" on "hanode2" + And Run "crm cluster join cluster -y -c hanode1" on "hanode2" + Then Cluster service is "started" on "hanode2" + And Service "sbd" is "started" on "hanode2" + And Resource "stonith-sbd" type "external/sbd" is "Started" + + @clean + Scenario: Configure diskless sbd in several stages(bsc#1175057) + Given Cluster service is "stopped" on "hanode1" + Given Cluster service is "stopped" on "hanode2" + When Run "crm cluster init ssh -y" on "hanode1" + And Run "crm cluster init csync2 -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" + 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" + And Run "crm cluster join csync2 -y -c hanode1" on "hanode2" + And Run "crm cluster join ssh_merge -y -c hanode1" on "hanode2" + And Run "crm cluster join cluster -y -c hanode1" on "hanode2" + Then Cluster service is "started" on "hanode2" + And Service "sbd" is "started" on "hanode2" + And Resource "stonith:external/sbd" not configured diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/crmsh-4.2.0+git.1595940615.c452cc00/test/unittests/test_bootstrap.py new/crmsh-4.2.0+git.1598257562.570eb99d/test/unittests/test_bootstrap.py --- old/crmsh-4.2.0+git.1595940615.c452cc00/test/unittests/test_bootstrap.py 2020-07-28 14:50:15.000000000 +0200 +++ new/crmsh-4.2.0+git.1598257562.570eb99d/test/unittests/test_bootstrap.py 2020-08-24 10:26:02.000000000 +0200 @@ -209,23 +209,12 @@ mock_update.assert_called_once_with() mock_status_done.assert_called_once_with() - @mock.patch('crmsh.bootstrap.invoke') - def test_manage_sbd_service_enable(self, mock_invoke): - self.sbd_inst._sbd_service_flag = True - self.sbd_inst.manage_sbd_service() - mock_invoke.assert_called_once_with("systemctl enable sbd.service") - - @mock.patch('crmsh.bootstrap.invoke') - def test_manage_sbd_service_disable(self, mock_invoke): - self.sbd_inst._sbd_service_flag = False - self.sbd_inst.manage_sbd_service() - mock_invoke.assert_called_once_with("systemctl disable sbd.service") - @mock.patch('crmsh.bootstrap.error') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('crmsh.bootstrap.SBDManager._get_sbd_device_from_config') - def test_configure_sbd_resource_error_primitive(self, mock_get_device, mock_invoke, mock_error): - self.sbd_inst._sbd_devices = ["/dev/sdb1"] + @mock.patch('crmsh.bootstrap.service_is_enabled') + def test_configure_sbd_resource_error_primitive(self, mock_enabled, mock_get_device, mock_invoke, mock_error): + mock_enabled.return_value = True mock_get_device.return_value = ["/dev/sdb1"] mock_invoke.return_value = False mock_error.side_effect = ValueError @@ -233,6 +222,7 @@ with self.assertRaises(ValueError): self.sbd_inst.configure_sbd_resource() + mock_enabled.assert_called_once_with("sbd.service") mock_get_device.assert_called_once_with() mock_invoke.assert_called_once_with("crm configure primitive stonith-sbd stonith:external/sbd pcmk_delay_max=30s") mock_error.assert_called_once_with("Can't create stonith-sbd primitive") @@ -240,8 +230,9 @@ @mock.patch('crmsh.bootstrap.error') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('crmsh.bootstrap.SBDManager._get_sbd_device_from_config') - def test_configure_sbd_resource_error_property(self, mock_get_device, mock_invoke, mock_error): - self.sbd_inst._sbd_devices = ["/dev/sdb1"] + @mock.patch('crmsh.bootstrap.service_is_enabled') + def test_configure_sbd_resource_error_property(self, mock_enabled, mock_get_device, mock_invoke, mock_error): + mock_enabled.return_value = True mock_get_device.return_value = ["/dev/sdb1"] mock_invoke.side_effect = [True, False] mock_error.side_effect = ValueError @@ -249,6 +240,7 @@ with self.assertRaises(ValueError): self.sbd_inst.configure_sbd_resource() + mock_enabled.assert_called_once_with("sbd.service") mock_get_device.assert_called_once_with() mock_invoke.assert_has_calls([ mock.call("crm configure primitive stonith-sbd stonith:external/sbd pcmk_delay_max=30s"), @@ -259,15 +251,18 @@ @mock.patch('crmsh.bootstrap.error') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('crmsh.bootstrap.SBDManager._get_sbd_device_from_config') - def test_configure_sbd_resource_diskless(self, mock_get_device, mock_invoke, mock_error): - self.sbd_inst_diskless._sbd_devices = None + @mock.patch('crmsh.bootstrap.service_is_enabled') + def test_configure_sbd_resource_diskless(self, mock_enabled, mock_get_device, mock_invoke, mock_error): + mock_enabled.return_value = True + mock_get_device.return_value = None mock_invoke.return_value = False mock_error.side_effect = ValueError with self.assertRaises(ValueError): self.sbd_inst_diskless.configure_sbd_resource() - mock_get_device.assert_not_called() + mock_enabled.assert_called_once_with("sbd.service") + mock_get_device.assert_called_once_with() mock_invoke.assert_called_once_with("crm configure property stonith-enabled=true stonith-watchdog-timeout=5s") mock_error.assert_called_once_with("Can't enable STONITH for diskless SBD") @@ -277,19 +272,22 @@ mock_exists.return_value = False self.sbd_inst.join_sbd("node1") mock_exists.assert_called_once_with("/etc/sysconfig/sbd") - mock_invoke.assert_not_called() + mock_invoke.assert_called_once_with("systemctl disable sbd.service") @mock.patch('crmsh.bootstrap.SBDManager._check_environment') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('os.path.exists') def test_join_sbd_config_disabled(self, mock_exists, mock_invoke, mock_check): mock_exists.return_value = True - mock_invoke.return_value = False + mock_invoke.side_effect = [False, True] self.sbd_inst.join_sbd("node1") mock_exists.assert_called_once_with("/etc/sysconfig/sbd") - mock_invoke.assert_called_once_with("ssh -o StrictHostKeyChecking=no root@node1 systemctl is-enabled sbd.service") + mock_invoke.assert_has_calls([ + mock.call("ssh -o StrictHostKeyChecking=no root@node1 systemctl is-enabled sbd.service"), + mock.call("systemctl disable sbd.service") + ]) mock_check.assert_not_called() @mock.patch('crmsh.bootstrap.status') @@ -300,13 +298,16 @@ @mock.patch('os.path.exists') def test_join_sbd(self, mock_exists, mock_invoke, mock_check, mock_get_device, mock_verify, mock_status): mock_exists.return_value = True - mock_invoke.return_value = True + mock_invoke.side_effect = [True, True] mock_get_device.return_value = ["/dev/sdb1"] self.sbd_inst.join_sbd("node1") mock_exists.assert_called_once_with("/etc/sysconfig/sbd") - mock_invoke.assert_called_once_with("ssh -o StrictHostKeyChecking=no root@node1 systemctl is-enabled sbd.service") + mock_invoke.assert_has_calls([ + mock.call("ssh -o StrictHostKeyChecking=no root@node1 systemctl is-enabled sbd.service"), + mock.call("systemctl enable sbd.service") + ]) mock_check.assert_called_once_with() mock_get_device.assert_called_once_with() mock_verify.assert_called_once_with(["/dev/sdb1"])
