def Run(self): """Main runner for this builder class. Runs build and prints summary. Returns: Whether the build succeeded. """ self._InitializeTrybotPatchPool() if self._run.options.bootstrap: bootstrap_stage = self._GetBootstrapStage() if bootstrap_stage: # BootstrapStage blocks on re-execution of cbuildbot. bootstrap_stage.Run() return bootstrap_stage.returncode == 0 print_report = True exception_thrown = False success = True sync_instance = None try: self.Initialize() sync_instance = self.GetSyncInstance() self._RunSyncStage(sync_instance) if self._run.ShouldPatchAfterSync(): # Filter out patches to manifest, since PatchChangesStage can't handle # them. Manifest patches are patched in the BootstrapStage. non_manifest_patches = self.patch_pool.FilterManifest( negate=True) if non_manifest_patches: self._RunStage(sync_stages.PatchChangesStage, non_manifest_patches) # Now that we have a fully synced & patched tree, we can let the builder # extract version information from the sources for this particular build. self.SetVersionInfo() if self._run.ShouldReexecAfterSync(): print_report = False success = self._ReExecuteInBuildroot(sync_instance) else: self._RunStage(report_stages.BuildReexecutionFinishedStage) self._RunStage(report_stages.ConfigDumpStage) self.RunStages() except Exception as ex: if isinstance(ex, failures_lib.ExitEarlyException): # One stage finished and exited early, not a failure. raise exception_thrown = True build_identifier, _ = self._run.GetCIDBHandle() buildbucket_id = build_identifier.buildbucket_id if results_lib.Results.BuildSucceededSoFar(self.buildstore, buildbucket_id): # If the build is marked as successful, but threw exceptions, that's a # problem. Print the traceback for debugging. if isinstance(ex, failures_lib.CompoundFailure): print(str(ex)) traceback.print_exc(file=sys.stdout) raise if not (print_report and isinstance(ex, failures_lib.StepFailure)): # If the failed build threw a non-StepFailure exception, we # should raise it. raise finally: if print_report: results_lib.WriteCheckpoint(self._run.options.buildroot) completion_instance = self.GetCompletionInstance() self._RunStage(report_stages.ReportStage, completion_instance) build_identifier, _ = self._run.GetCIDBHandle() buildbucket_id = build_identifier.buildbucket_id success = results_lib.Results.BuildSucceededSoFar( self.buildstore, buildbucket_id) if exception_thrown and success: success = False logging.PrintBuildbotStepWarnings() print("""\ Exception thrown, but all stages marked successful. This is an internal error, because the stage that threw the exception should be marked as failing.""") return success
def _ReExecuteInBuildroot(self, sync_instance): """Reexecutes self in buildroot and returns True if build succeeds. This allows the buildbot code to test itself when changes are patched for buildbot-related code. This is a no-op if the buildroot == buildroot of the running chromite checkout. Args: sync_instance: Instance of the sync stage that was run to sync. Returns: True if the Build succeeded. """ if not self._run.options.resume: results_lib.WriteCheckpoint(self._run.options.buildroot) args = sync_stages.BootstrapStage.FilterArgsForTargetCbuildbot( self._run.options.buildroot, constants.PATH_TO_CBUILDBOT, self._run.options) # Specify a buildroot explicitly (just in case, for local trybot). # Suppress any timeout options given from the commandline in the # invoked cbuildbot; our timeout will enforce it instead. args += [ '--resume', '--timeout', '0', '--notee', '--nocgroups', '--buildroot', os.path.abspath(self._run.options.buildroot) ] # Set --version. Note that --version isn't legal without --buildbot. if (self._run.options.buildbot and hasattr(self._run.attrs, 'manifest_manager')): ver = self._run.attrs.manifest_manager.current_version args += ['--version', ver] pool = getattr(sync_instance, 'pool', None) if pool: filename = os.path.join(self._run.options.buildroot, 'validation_pool.dump') pool.Save(filename) args += ['--validation_pool', filename] # Reset the cache dir so that the child will calculate it automatically. if not self._run.options.cache_dir_specified: commandline.BaseParser.ConfigureCacheDir(None) with tempfile.NamedTemporaryFile(prefix='metadata', mode='w') as metadata_file: metadata_file.write(self._run.attrs.metadata.GetJSON()) metadata_file.flush() args += ['--metadata_dump', metadata_file.name] # Re-run the command in the buildroot. # Finally, be generous and give the invoked cbuildbot 30s to shutdown # when something occurs. It should exit quicker, but the sigterm may # hit while the system is particularly busy. return_obj = cros_build_lib.run(args, cwd=self._run.options.buildroot, error_code_ok=True, kill_timeout=30) return return_obj.returncode == 0