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 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 update_scsi_devices_without_restart( runner: CommandRunner, cluster_state: _Element, resource_el: _Element, id_provider: IdProvider, devices_list: Iterable[str], ) -> None: """ Update scsi devices without restart of stonith resource or other resources. runner -- command runner instance cluster_state -- status of the cluster resource_el -- resource element being updated id_provider -- elements' ids generator device_list -- list of updated scsi devices """ resource_id = resource_el.get("id", "") roles_with_nodes = get_resource_state(cluster_state, resource_id) if "Started" not in roles_with_nodes: raise LibraryError( ReportItem.error( reports.messages.StonithRestartlessUpdateUnableToPerform( f"resource '{resource_id}' is not running on any node", reason_type=reports.const. STONITH_RESTARTLESS_UPDATE_UNABLE_TO_PERFORM_REASON_NOT_RUNNING, ))) if len(roles_with_nodes["Started"]) != 1: # TODO: do we want to be able update cloned fence_scsi? Or just case # when it's running on more than 1 node? It is possible but we need to # update more lrm_rsc_op elements raise LibraryError( ReportItem.error( reports.messages.StonithRestartlessUpdateUnableToPerform( f"resource '{resource_id}' is running on more than 1 node") )) node_name = roles_with_nodes["Started"][0] new_instance_attrs = {"devices": ",".join(sorted(devices_list))} arrange_first_instance_attributes(resource_el, new_instance_attrs, id_provider) lrm_rsc_op_start_list = _get_lrm_rsc_op_elements(get_root(resource_el), resource_id, node_name, "start") if len(lrm_rsc_op_start_list) == 1: _update_digest_attrs_in_lrm_rsc_op( lrm_rsc_op_start_list[0], get_resource_digests( runner, resource_id, node_name, new_instance_attrs, ), ) else: raise LibraryError( ReportItem.error( reports.messages.StonithRestartlessUpdateUnableToPerform( "lrm_rsc_op element for start operation was not found"))) monitor_attrs_list = _get_monitor_attrs(resource_el) lrm_rsc_op_monitor_list = _get_lrm_rsc_op_elements(get_root(resource_el), resource_id, node_name, "monitor") if len(lrm_rsc_op_monitor_list) != len(monitor_attrs_list): raise LibraryError( ReportItem.error( reports.messages.StonithRestartlessUpdateUnableToPerform( ("number of lrm_rsc_op and op elements for monitor " "operation differs")))) for monitor_attrs in monitor_attrs_list: lrm_rsc_op_list = _get_lrm_rsc_op_elements( get_root(resource_el), resource_id, node_name, "monitor", monitor_attrs["interval"], ) if len(lrm_rsc_op_list) == 1: _update_digest_attrs_in_lrm_rsc_op( lrm_rsc_op_list[0], get_resource_digests( runner, resource_id, node_name, new_instance_attrs, crm_meta_attributes=monitor_attrs, ), ) else: raise LibraryError( ReportItem.error( reports.messages.StonithRestartlessUpdateUnableToPerform( ("monitor lrm_rsc_op element for resource " f"'{resource_id}', node '{node_name}' and interval " f"'{monitor_attrs['interval']}' not found"))))