docs: def run(self):
          """
          Runs all jobs.
  
          Returns:
              All errors encountered as a list of list.
              [[error_dicts for job 1], [error_dicts for job 2], ....]
  
          Raises:
              ValidationError: if a job fails validation
              ReturnCodeError: if the process has a return code different from 0
              NonRecoverableError: if an unrecoverable occurs
              MaxCorrectionsPerJobError: if max_errors_per_job is reached
              MaxCorrectionsError: if max_errors is reached
              MaxCorrectionsPerHandlerError: if max_errors_per_handler is reached
          """
          cwd = os.getcwd()
  
          with ScratchDir(self.scratch_dir, create_symbolic_link=True,
                          copy_to_current_on_exit=True,
                          copy_from_current_on_enter=True) as temp_dir:
              self.total_errors = 0
              start = datetime.datetime.now()
              logger.info("Run started at {} in {}.".format(
                  start, temp_dir))
              v = sys.version.replace("\n", " ")
              logger.info("Custodian running on Python version {}".format(v))
              logger.info("Hostname: {}, Cluster: {}".format(
                  *get_execution_host_info()))
  
              try:
                  # skip jobs until the restart
                  for job_n, job in islice(enumerate(self.jobs, 1),
                                           self.restart, None):
                      self._run_job(job_n, job)
                      # We do a dump of the run log after each job.
                      dumpfn(self.run_log, Custodian.LOG_FILE, cls=MontyEncoder,
                             indent=4)
                      # Checkpoint after each job so that we can recover from last
                      # point and remove old checkpoints
                      if self.checkpoint:
                          self.restart = job_n
                          Custodian._save_checkpoint(cwd, job_n)
              except CustodianError as ex:
                  logger.error(ex.message)
                  if ex.raises:
                      raise
              finally:
                  # Log the corrections to a json file.
                  logger.info("Logging to {}...".format(Custodian.LOG_FILE))
                  dumpfn(self.run_log, Custodian.LOG_FILE, cls=MontyEncoder,
                         indent=4)
                  end = datetime.datetime.now()
                  logger.info("Run ended at {}.".format(end))
                  run_time = end - start
                  logger.info("Run completed. Total time taken = {}."
                              .format(run_time))
                  if self.gzipped_output:
                      gzip_dir(".")
  
              # Cleanup checkpoint files (if any) if run is successful.
              Custodian._delete_checkpoints(cwd)
  
          return self.run_log