diff --git a/crmsh/bootstrap.py b/crmsh/bootstrap.py index ec0022f3d..dd438ff20 100644 --- a/crmsh/bootstrap.py +++ b/crmsh/bootstrap.py @@ -66,6 +66,7 @@ PCMK_REMOTE_AUTH = "/etc/pacemaker/authkey" COROSYNC_CONF_ORIG = tmpfiles.create()[1] SERVICES_STOP_LIST = ["corosync-qdevice.service", "corosync.service", "hawk.service", CSYNC2_SERVICE] +SERVICES_DISABLE_LIST = ["pacemaker.service", "sbd.service"] WATCHDOG_CFG = "/etc/modules-load.d/watchdog.conf" BOOTH_DIR = "/etc/booth" BOOTH_CFG = "/etc/booth/booth.conf" @@ -832,7 +833,7 @@ def start_pacemaker(node_list=[], enable_flag=False): except ValueError as err: node_list.remove(node) logger.error(err) - logger.info("Starting pacemaker.service on %s", ', '.join(node_list) or utils.this_node()) + logger.info("Starting and enable pacemaker.service on %s", ', '.join(node_list) or utils.this_node()) return service_manager.start_service("pacemaker.service", enable=enable_flag, node_list=node_list) @@ -2357,15 +2358,19 @@ def get_cluster_node_ip(node: str) -> str: return ip -def stop_services(stop_list, remote_addr=None): +def stop_and_disable_services(remote_addr=None): """ - Stop cluster related service + Stop and disable cluster related service """ service_manager = ServiceManager() - for service in stop_list: + for service in SERVICES_STOP_LIST: if service_manager.service_is_active(service, remote_addr=remote_addr): - logger.info("Stopping the %s on %s", service, remote_addr if remote_addr else utils.this_node()) + logger.info("Stopping and disable %s on node %s", service, remote_addr or utils.this_node()) service_manager.stop_service(service, disable=True, remote_addr=remote_addr) + for service in SERVICES_DISABLE_LIST: + if service_manager.service_is_enabled(service, remote_addr=remote_addr): + logger.info("Disable %s on node %s", service, remote_addr or utils.this_node()) + service_manager.disable_service(service, remote_addr=remote_addr) def rm_configuration_files(remote=None): @@ -2405,7 +2410,7 @@ def remove_node_from_cluster(node, dead_node=False): node_ip = get_cluster_node_ip(node) if not dead_node: - stop_services(SERVICES_STOP_LIST, remote_addr=node) + stop_and_disable_services(remote_addr=node) qdevice.QDevice.remove_qdevice_db([node]) rm_configuration_files(node) @@ -2818,7 +2823,7 @@ def remove_self(force_flag=False): print(stdout) else: # disable and stop cluster - stop_services(SERVICES_STOP_LIST) + stop_and_disable_services() qdevice.QDevice.remove_certification_files_on_qnetd() qdevice.QDevice.remove_qdevice_db([utils.this_node()]) rm_configuration_files() diff --git a/test/unittests/test_bootstrap.py b/test/unittests/test_bootstrap.py index 9a7cffb65..7bb901307 100644 --- a/test/unittests/test_bootstrap.py +++ b/test/unittests/test_bootstrap.py @@ -1804,14 +1804,17 @@ def test_get_cluster_node_ip(self, mock_get_values, mock_get_iplist): mock_get_values.assert_called_once_with("nodelist.node.ring0_addr") mock_get_iplist.assert_called_once_with('node1') + @mock.patch('crmsh.service_manager.ServiceManager.disable_service') + @mock.patch('crmsh.service_manager.ServiceManager.service_is_enabled') @mock.patch('crmsh.utils.this_node') @mock.patch('crmsh.service_manager.ServiceManager.stop_service') @mock.patch('logging.Logger.info') @mock.patch('crmsh.service_manager.ServiceManager.service_is_active') - def test_stop_services(self, mock_active, mock_status, mock_stop, mock_this_node): + def test_stop_and_disable_services(self, mock_active, mock_status, mock_stop, mock_this_node, mock_enabled, mock_disable): mock_active.side_effect = [True, True, True, True] - mock_this_node.side_effect = ['node1', 'node1', 'node1', 'node1'] - bootstrap.stop_services(bootstrap.SERVICES_STOP_LIST) + mock_enabled.side_effect = [True, True] + mock_this_node.side_effect = ['node1', 'node1', 'node1', 'node1', 'node1', 'node1'] + bootstrap.stop_and_disable_services() mock_active.assert_has_calls([ mock.call("corosync-qdevice.service", remote_addr=None), mock.call("corosync.service", remote_addr=None), @@ -1819,10 +1822,11 @@ def test_stop_services(self, mock_active, mock_status, mock_stop, mock_this_node mock.call("csync2.socket", remote_addr=None) ]) mock_status.assert_has_calls([ - mock.call('Stopping the %s on %s', 'corosync-qdevice.service', 'node1'), - mock.call('Stopping the %s on %s', 'corosync.service', 'node1'), - mock.call('Stopping the %s on %s', 'hawk.service', 'node1'), - mock.call('Stopping the %s on %s', 'csync2.socket', 'node1') + mock.call('Stopping and disable %s on node %s', 'corosync.service', 'node1'), + mock.call('Stopping and disable %s on node %s', 'hawk.service', 'node1'), + mock.call('Stopping and disable %s on node %s', 'csync2.socket', 'node1'), + mock.call('Disable %s on node %s', 'pacemaker.service', 'node1'), + mock.call('Disable %s on node %s', 'sbd.service', 'node1'), ]) mock_stop.assert_has_calls([ mock.call("corosync-qdevice.service", disable=True, remote_addr=None), @@ -1836,7 +1840,7 @@ def test_stop_services(self, mock_active, mock_status, mock_stop, mock_this_node @mock.patch('crmsh.utils.fatal') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('logging.Logger.info') - @mock.patch('crmsh.bootstrap.stop_services') + @mock.patch('crmsh.bootstrap.stop_and_disable_services') @mock.patch('crmsh.bootstrap.get_cluster_node_ip') @mock.patch('crmsh.xmlutil.CrmMonXmlParser') def test_remove_node_from_cluster_rm_node_failed(self, mock_crm_mon_parser, mock_get_ip, mock_stop, mock_status, mock_invoke, mock_error, mock_rm_conf_files, mock_call_delnode): @@ -1853,7 +1857,7 @@ def test_remove_node_from_cluster_rm_node_failed(self, mock_crm_mon_parser, mock mock_get_ip.assert_called_once_with('node1') mock_status.assert_called_once_with("Removing node %s from CIB", "node1") - mock_stop.assert_called_once_with(bootstrap.SERVICES_STOP_LIST, remote_addr="node1") + mock_stop.assert_called_once_with(remote_addr="node1") mock_invoke.assert_not_called() mock_call_delnode.assert_called_once_with("node1") mock_error.assert_called_once_with("Failed to remove node1.") @@ -1864,7 +1868,7 @@ def test_remove_node_from_cluster_rm_node_failed(self, mock_crm_mon_parser, mock @mock.patch('crmsh.bootstrap.invokerc') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('logging.Logger.info') - @mock.patch('crmsh.bootstrap.stop_services') + @mock.patch('crmsh.bootstrap.stop_and_disable_services') @mock.patch('crmsh.bootstrap.get_cluster_node_ip') @mock.patch('crmsh.xmlutil.CrmMonXmlParser') def test_remove_node_from_cluster_rm_csync_failed(self, mock_crm_mon_parser, mock_get_ip, mock_stop, mock_status, mock_invoke, mock_invokerc, mock_error, mock_rm_conf_files, mock_call_delnode): @@ -1882,7 +1886,7 @@ def test_remove_node_from_cluster_rm_csync_failed(self, mock_crm_mon_parser, moc mock_get_ip.assert_called_once_with('node1') mock_status.assert_called_once_with("Removing node %s from CIB", "node1") - mock_stop.assert_called_once_with(bootstrap.SERVICES_STOP_LIST, remote_addr="node1") + mock_stop.assert_called_once_with(remote_addr="node1") mock_invoke.assert_not_called() mock_call_delnode.assert_called_once_with("node1") mock_invokerc.assert_has_calls([ @@ -1904,7 +1908,7 @@ def test_remove_node_from_cluster_rm_csync_failed(self, mock_crm_mon_parser, moc @mock.patch('crmsh.bootstrap.invokerc') @mock.patch('crmsh.bootstrap.invoke') @mock.patch('logging.Logger.info') - @mock.patch('crmsh.bootstrap.stop_services') + @mock.patch('crmsh.bootstrap.stop_and_disable_services') @mock.patch('crmsh.bootstrap.get_cluster_node_ip') @mock.patch('crmsh.xmlutil.CrmMonXmlParser') def test_remove_node_from_cluster_hostname(self, mock_crm_mon_parser, mock_get_ip, mock_stop, mock_status, @@ -1928,7 +1932,7 @@ def test_remove_node_from_cluster_hostname(self, mock_crm_mon_parser, mock_get_i mock.call("Removing node %s from CIB", "node1"), mock.call("Propagating configuration changes across the remaining nodes") ]) - mock_stop.assert_called_once_with(bootstrap.SERVICES_STOP_LIST, remote_addr="node1") + mock_stop.assert_called_once_with(remote_addr="node1") mock_cal_delnode.assert_called_once_with("node1") mock_invoke.assert_has_calls([ mock.call("corosync-cfgtool -R")