Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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