def run( self, env, resource_id, node=None, master=False, lifetime=None, wait=False ): # validate env.ensure_wait_satisfiable(wait) # raises on error report_list = [] resource_el = resource.common.find_one_resource_and_report( get_resources(env.get_cib()), resource_id, report_list, ) if resource_el is not None: report_list.extend(self._validate(resource_el, master)) env.report_processor.process_list(report_list) # raises on error # get current status for wait processing if wait is not False: resource_running_on_before = get_resource_state( env.get_cluster_state(), resource_id ) # run the action stdout, stderr, retval = self._run_action( env.cmd_runner(), resource_id, node=node, master=master, lifetime=lifetime ) if retval != 0: if ( f"Resource '{resource_id}' not moved: active in 0 locations" in stderr ): raise LibraryError( self._report_action_stopped_resource(resource_id) ) raise LibraryError( self._report_action_pcmk_error(resource_id, stdout, stderr) ) env.report_processor.process( self._report_action_pcmk_success(resource_id, stdout, stderr) ) # process wait if wait is not False: wait_for_idle(env.cmd_runner(), env.get_wait_timeout(wait)) resource_running_on_after = get_resource_state( env.get_cluster_state(), resource_id ) env.report_processor.process( self._report_wait_result( resource_id, node, resource_running_on_before, resource_running_on_after, ) )
def __do_push_cib(self, cmd_runner, push_strategy, wait): timeout = self._get_wait_timeout(wait) push_strategy() self._cib_upgrade_reported = False self.__loaded_cib_diff_source = None self.__loaded_cib_to_modify = None if self.is_cib_live and timeout is not False: wait_for_idle(cmd_runner, timeout)
def __do_push_cib(self, cmd_runner, push_strategy, wait): timeout = self.get_wait_timeout(wait) push_strategy() self._cib_upgrade_reported = False self.__loaded_cib_diff_source = None self.__loaded_cib_diff_source_feature_set = None self.__loaded_cib_to_modify = None if self.is_cib_live and timeout is not False: wait_for_idle(cmd_runner, timeout)
def unmove_unban( env, resource_id, node=None, master=False, expired=False, wait=False ): """ Remove all constraints created by move and ban LibraryEnvironment env string resource_id -- id of a resource to be unmoved/unbanned string node -- node to limit unmoving/unbanning to, all nodes if None bool master -- only remove constraints for Master role bool expired -- only remove constrains which have already expired mixed wait -- flag for controlling waiting for pacemaker idle mechanism """ # validate env.ensure_wait_satisfiable(wait) # raises on error report_list = [] resource_el = resource.common.find_one_resource_and_report( get_resources(env.get_cib()), resource_id, report_list, ) if resource_el is not None: report_list.extend( resource.common.validate_unmove_unban(resource_el, master) ) if ( expired and not has_resource_unmove_unban_expired_support(env.cmd_runner()) ): report_list.append( reports.resource_unmove_unban_pcmk_expired_not_supported() ) env.report_processor.process_list(report_list) # raises on error # run the action stdout, stderr, retval = resource_unmove_unban( env.cmd_runner(), resource_id, node=node, master=master, expired=expired ) if retval != 0: raise LibraryError( reports.resource_unmove_unban_pcmk_error( resource_id, stdout, stderr ) ) env.report_processor.process( reports.resource_unmove_unban_pcmk_success(resource_id, stdout, stderr) ) # process wait if wait is not False: wait_for_idle(env.cmd_runner(), env.get_wait_timeout(wait)) env.report_processor.process( info_resource_state(env.get_cluster_state(), resource_id) )
def push_cib(self, cib, wait=False): timeout = self._get_wait_timeout(wait) #etree returns bytes: b'xml' #python 3 removed .encode() from bytes #run(...) calls subprocess.Popen.communicate which calls encode... #so here is bytes to str conversion self._push_cib_xml(etree.tostring(cib).decode()) if timeout is not False: wait_for_idle(self.cmd_runner(), timeout)
def run(self, env, resource_id, node=None, master=False, lifetime=None, wait=False): # validate env.ensure_wait_satisfiable(wait) # raises on error report_list = [] resource_el = resource.common.find_one_resource_and_report( get_resources(env.get_cib()), resource_id, report_list, ) if resource_el is not None: report_list.extend(self._validate(resource_el, master)) env.report_processor.process_list(report_list) # raises on error # get current status for wait processing if wait is not False: resource_running_on_before = get_resource_state( env.get_cluster_state(), resource_id) # run the action stdout, stderr, retval = self._run_action(env.cmd_runner(), resource_id, node=node, master=master, lifetime=lifetime) if retval != 0: if (f"Resource '{resource_id}' not moved: active in 0 locations" in stderr): raise LibraryError( self._report_action_stopped_resource(resource_id)) raise LibraryError( self._report_action_pcmk_error(resource_id, stdout, stderr)) env.report_processor.process( self._report_action_pcmk_success(resource_id, stdout, stderr)) # process wait if wait is not False: wait_for_idle(env.cmd_runner(), env.get_wait_timeout(wait)) resource_running_on_after = get_resource_state( env.get_cluster_state(), resource_id) env.report_processor.process( self._report_wait_result( resource_id, node, resource_running_on_before, resource_running_on_after, ))
def unmove_unban(env, resource_id, node=None, master=False, expired=False, wait=False): """ Remove all constraints created by move and ban LibraryEnvironment env string resource_id -- id of a resource to be unmoved/unbanned string node -- node to limit unmoving/unbanning to, all nodes if None bool master -- only remove constraints for Master role bool expired -- only remove constrains which have already expired mixed wait -- flag for controlling waiting for pacemaker idle mechanism """ # validate env.ensure_wait_satisfiable(wait) # raises on error report_list = [] resource_el = resource.common.find_one_resource_and_report( get_resources(env.get_cib()), resource_id, report_list, ) if resource_el is not None: report_list.extend( resource.common.validate_unmove_unban(resource_el, master)) if (expired and not has_resource_unmove_unban_expired_support(env.cmd_runner())): report_list.append( reports.resource_unmove_unban_pcmk_expired_not_supported()) env.report_processor.process_list(report_list) # raises on error # run the action stdout, stderr, retval = resource_unmove_unban(env.cmd_runner(), resource_id, node=node, master=master, expired=expired) if retval != 0: raise LibraryError( reports.resource_unmove_unban_pcmk_error(resource_id, stdout, stderr)) env.report_processor.process( reports.resource_unmove_unban_pcmk_success(resource_id, stdout, stderr)) # process wait if wait is not False: wait_for_idle(env.cmd_runner(), env.get_wait_timeout(wait)) env.report_processor.process( info_resource_state(env.get_cluster_state(), resource_id))
def wait_for_idle(self, timeout: int = 0) -> None: """ Wait for the cluster to settle down. timeout -- timeout in seconds, if less than 0 wait will be skipped, if 0 wait indefinitely """ if timeout < 0: # timeout is turned off return self.report_processor.report( ReportItem.info(reports.messages.WaitForIdleStarted(timeout))) wait_for_idle(self.cmd_runner(), timeout)
def test_wait_error_timeout(self): expected_stdout = "some info" expected_stderr = "some error" expected_retval = 62 mock_runner = mock.MagicMock(spec_set=CommandRunner) mock_runner.run.return_value = ( expected_stdout, expected_stderr, expected_retval ) assert_raise_library_error( lambda: lib.wait_for_idle(mock_runner), ( Severity.ERROR, report_codes.WAIT_FOR_IDLE_TIMED_OUT, { "reason": expected_stderr + "\n" + expected_stdout, } ) ) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"] )
def test_wait_success(self): expected_stdout = "expected output" expected_stderr = "expected stderr" expected_retval = 0 mock_runner = get_runner(expected_stdout, expected_stderr, expected_retval) self.assertEqual(None, lib.wait_for_idle(mock_runner)) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"])
def test_wait_success(self): expected_stdout = "expected output" expected_stderr = "expected stderr" expected_retval = 0 mock_runner = mock.MagicMock(spec_set=CommandRunner) mock_runner.run.return_value = (expected_stdout, expected_stderr, expected_retval) self.assertEqual(None, lib.wait_for_idle(mock_runner)) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"])
def test_wait_error(self): expected_stdout = "some info" expected_stderr = "some error" expected_retval = 1 mock_runner = get_runner(expected_stdout, expected_stderr, expected_retval) assert_raise_library_error( lambda: lib.wait_for_idle(mock_runner), (Severity.ERROR, report_codes.WAIT_FOR_IDLE_ERROR, { "reason": expected_stderr + "\n" + expected_stdout, })) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"])
def test_wait_success(self): expected_stdout = "expected output" expected_stderr = "expected stderr" expected_retval = 0 mock_runner = get_runner( expected_stdout, expected_stderr, expected_retval ) self.assertEqual(None, lib.wait_for_idle(mock_runner)) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"] )
def test_wait_success(self): expected_stdout = "expected output" expected_stderr = "expected stderr" expected_retval = 0 mock_runner = mock.MagicMock(spec_set=CommandRunner) mock_runner.run.return_value = ( expected_stdout, expected_stderr, expected_retval ) self.assertEqual(None, lib.wait_for_idle(mock_runner)) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"] )
def test_wait_error(self): expected_stdout = "some info" expected_stderr = "some error" expected_retval = 1 mock_runner = get_runner( expected_stdout, expected_stderr, expected_retval ) assert_raise_library_error( lambda: lib.wait_for_idle(mock_runner), ( Severity.ERROR, report_codes.WAIT_FOR_IDLE_ERROR, { "reason": expected_stderr + "\n" + expected_stdout, } ) ) mock_runner.run.assert_called_once_with( [self.path("crm_resource"), "--wait"] )