Example #1
0
    def Run(self, force=False):
        """Do the actual work of the Cron. Will first check if DueToRun is True.

    CronJob object must be leased for Run() to be called.

    Args:
      force: If True, the job will run even if DueToRun() returns False.

    Raises:
      LockError: if the object is not locked.
    """
        if not self.leased_until or self.leased_until < rdfvalue.RDFDatetime.Now(
        ):
            raise LockError("CronJob must be leased for Run() to be called.")

        self.TerminateExpiredRun()

        # If currently running flow has finished, update our state.
        runs_base = rdfvalue.RDFURN("aff4:/cron").Add(self.job_id)
        if self.current_run_id:
            current_run_urn = runs_base.Add("F:%X" % self.current_run_id)
            current_flow = aff4.FACTORY.Open(current_run_urn, token=self.token)
            runner = current_flow.GetRunner()
            if not runner.IsRunning():
                if runner.context.state == "ERROR":
                    status = rdf_cronjobs.CronJobRunStatus(
                        status=rdf_cronjobs.CronJobRunStatus.Status.ERROR)
                    stats.STATS.IncrementCounter("cron_job_failure",
                                                 fields=[self.job_id])
                else:
                    status = rdf_cronjobs.CronJobRunStatus(
                        status=rdf_cronjobs.CronJobRunStatus.Status.OK)
                    elapsed = rdfvalue.RDFDatetime.Now() - self.last_run_time
                    stats.STATS.RecordEvent("cron_job_latency",
                                            elapsed,
                                            fields=[self.job_id])

                data_store.REL_DB.UpdateCronJob(self.job_id,
                                                last_run_status=status,
                                                current_run_id=None)

        if not force and not self.DueToRun():
            return

        # Make sure the flow is created with cron job as a parent folder.
        self.cron_args.flow_runner_args.base_session_id = runs_base

        flow_urn = flow.GRRFlow.StartFlow(
            runner_args=self.cron_args.flow_runner_args,
            args=self.cron_args.flow_args,
            token=self.token,
            sync=False)

        self.current_run_id = int(flow_urn.Basename()[2:], 16)
        data_store.REL_DB.UpdateCronJob(
            self.job_id,
            last_run_time=rdfvalue.RDFDatetime.Now(),
            current_run_id=self.current_run_id)
Example #2
0
 def StopCurrentRun(self, reason="Cron lifetime exceeded.", force=True):
   current_flow_urn = self.Get(self.Schema.CURRENT_FLOW_URN)
   if current_flow_urn:
     flow.GRRFlow.TerminateFlow(
         current_flow_urn, reason=reason, force=force, token=self.token)
     self.Set(
         self.Schema.LAST_RUN_STATUS,
         rdf_cronjobs.CronJobRunStatus(
             status=rdf_cronjobs.CronJobRunStatus.Status.TIMEOUT))
     self.DeleteAttribute(self.Schema.CURRENT_FLOW_URN)
     self.Flush()
Example #3
0
    def StopCurrentRun(self, reason="Cron lifetime exceeded.", force=True):
        """Stops the currently active run if there is one."""
        if not self.current_run_id:
            return

        runs_base = rdfvalue.RDFURN("aff4:/cron").Add(self.job_id)
        current_run_urn = runs_base.Add("F:%X" % self.current_run_id)
        flow.GRRFlow.TerminateFlow(current_run_urn,
                                   reason=reason,
                                   force=force,
                                   token=self.token)

        status = rdf_cronjobs.CronJobRunStatus(
            status=rdf_cronjobs.CronJobRunStatus.Status.TIMEOUT)
        data_store.REL_DB.UpdateCronJob(self.job_id,
                                        last_run_status=status,
                                        current_run_id=None)
Example #4
0
    def Run(self, force=False):
        """Do the actual work of the Cron. Will first check if DueToRun is True.

    CronJob object must be locked (i.e. opened via OpenWithLock) for Run() to be
    called.

    Args:
      force: If True, the job will run no matter what (i.e. even if DueToRun()
             returns False).

    Raises:
      LockError: if the object is not locked.
    """
        if not self.locked:
            raise aff4.LockError(
                "CronJob must be locked for Run() to be called.")

        self.KillOldFlows()

        # If currently running flow has finished, update our state.
        current_flow_urn = self.Get(self.Schema.CURRENT_FLOW_URN)
        if current_flow_urn:
            current_flow = aff4.FACTORY.Open(current_flow_urn,
                                             token=self.token)
            runner = current_flow.GetRunner()
            if not runner.IsRunning():
                if runner.context.state == rdf_flows.FlowContext.State.ERROR:
                    self.Set(
                        self.Schema.LAST_RUN_STATUS,
                        rdf_cronjobs.CronJobRunStatus(
                            status=rdf_cronjobs.CronJobRunStatus.Status.ERROR))
                    stats.STATS.IncrementCounter("cron_job_failure",
                                                 fields=[self.urn.Basename()])
                else:
                    self.Set(
                        self.Schema.LAST_RUN_STATUS,
                        rdf_cronjobs.CronJobRunStatus(
                            status=rdf_cronjobs.CronJobRunStatus.Status.OK))

                    start_time = self.Get(self.Schema.LAST_RUN_TIME)
                    elapsed = time.time() - start_time.AsSecondsFromEpoch()
                    stats.STATS.RecordEvent("cron_job_latency",
                                            elapsed,
                                            fields=[self.urn.Basename()])

                self.DeleteAttribute(self.Schema.CURRENT_FLOW_URN)
                self.Flush()

        if not force and not self.DueToRun():
            return

        # Make sure the flow is created with cron job as a parent folder.
        cron_args = self.Get(self.Schema.CRON_ARGS)
        cron_args.flow_runner_args.base_session_id = self.urn

        flow_urn = flow.GRRFlow.StartFlow(
            runner_args=cron_args.flow_runner_args,
            args=cron_args.flow_args,
            token=self.token,
            sync=False)

        self.Set(self.Schema.CURRENT_FLOW_URN, flow_urn)
        self.Set(self.Schema.LAST_RUN_TIME, rdfvalue.RDFDatetime.Now())
        self.Flush()