def InitializeContext(self, args): """Initializes the context of this flow.""" if args is None: args = rdf_flow_runner.FlowRunnerArgs() output_plugins_states = [] for plugin_descriptor in args.output_plugins: if not args.client_id: self.Log( "Not initializing output plugin %s as flow does not run on " "the client.", plugin_descriptor.plugin_name) continue output_base_urn = self.session_id.Add(OUTPUT_PLUGIN_BASE_SUFFIX) plugin_class = plugin_descriptor.GetPluginClass() plugin = plugin_class(self.flow_obj.output_urn, args=plugin_descriptor.plugin_args, output_base_urn=output_base_urn, token=self.token) try: plugin.InitializeState() # TODO(amoser): Those do not need to be inside the state, they # could be part of the plugin descriptor. plugin.state["logs"] = [] plugin.state["errors"] = [] output_plugins_states.append( rdf_flow_runner.OutputPluginState( plugin_state=plugin.state, plugin_descriptor=plugin_descriptor)) except Exception as e: # pylint: disable=broad-except logging.info( "Plugin %s failed to initialize (%s), ignoring it.", plugin, e) parent_creator = None if self.parent_runner: parent_creator = self.parent_runner.context.creator context = rdf_flow_runner.FlowContext( create_time=rdfvalue.RDFDatetime.Now(), creator=parent_creator or self.token.username, current_state="Start", output_plugins_states=output_plugins_states, state=rdf_flow_runner.FlowContext.State.RUNNING, ) return context
def InitFromFlowObject(self, flow_obj, with_args=True, with_progress=False, with_state_and_context=False): try: self.flow_id = flow_obj.flow_id self.client_id = flow_obj.client_id # TODO(amoser): Get rid of all urns. self.urn = flow_obj.long_flow_id self.name = flow_obj.flow_class_name self.started_at = flow_obj.create_time self.last_active_at = flow_obj.last_update_time self.creator = flow_obj.creator if flow_obj.client_crash_info: self.state = "CLIENT_CRASHED" elif flow_obj.pending_termination: self.state = "ERROR" self.status = ("Pending termination: %s" % flow_obj.pending_termination.reason) else: context_state_map = {1: "RUNNING", 2: "TERMINATED", 3: "ERROR"} self.state = context_state_map[int(flow_obj.flow_state)] if with_state_and_context: outstanding_requests = (flow_obj.next_outbound_id - flow_obj.next_request_to_process) self.context = rdf_flow_runner.FlowContext( # TODO(amoser): No need to set this in all cases once the legacy API # is removed. client_resources=rdf_client_stats.ClientResources( cpu_usage=rdf_client_stats.CpuSeconds()), create_time=flow_obj.create_time, creator=flow_obj.creator, current_state=flow_obj.current_state, next_outbound_id=flow_obj.next_outbound_id, outstanding_requests=outstanding_requests, state=self.state, # TODO(amoser): Get rid of all urns. session_id=flow_obj.long_flow_id, ) if flow_obj.output_plugins_states: self.context.output_plugins_states = flow_obj.output_plugins_states if flow_obj.network_bytes_sent: self.context.network_bytes_sent = flow_obj.network_bytes_sent self.context.client_resources.network_bytes_sent = ( flow_obj.network_bytes_sent) if flow_obj.cpu_time_used: self.context.client_resources.cpu_time_used = flow_obj.cpu_time_used if flow_obj.error_message: self.context.status = flow_obj.error_message if flow_obj.backtrace: self.context.backtrace = flow_obj.backtrace if with_args: try: self.args = flow_obj.args except ValueError: # If args class name has changed, ValueError will be raised. Handling # this gracefully - we should still try to display some useful info # about the flow. pass if with_progress: flow_cls = self._GetFlowClass() if flow_cls: self.progress = flow_cls(flow_obj).GetProgress() self.runner_args = rdf_flow_runner.FlowRunnerArgs( client_id=flow_obj.client_id, flow_name=flow_obj.flow_class_name, notify_to_user=flow_base.FlowBase( flow_obj).ShouldSendNotifications()) if flow_obj.output_plugins: self.runner_args.output_plugins = flow_obj.output_plugins if flow_obj.HasField("cpu_limit"): self.runner_args.cpu_limit = flow_obj.cpu_limit if flow_obj.HasField("network_bytes_limit"): self.runner_args.cpu_limit = flow_obj.network_bytes_limit if flow_obj.original_flow.flow_id: self.original_flow = ApiFlowReference().FromFlowReference( flow_obj.original_flow) if with_state_and_context and flow_obj.persistent_data.ToDict(): self.state_data = ( api_call_handler_utils.ApiDataObject().InitFromDataObject( flow_obj.persistent_data)) except Exception as e: # pylint: disable=broad-except self.internal_error = "Error while opening flow: %s" % str(e) return self