def _abandonOnFailure(self, rc): if not isinstance(rc, int): log.msg("weird, _abandonOnFailure was given rc=%s (%s)" % (rc, type(rc))) assert isinstance(rc, int) if rc != 0: raise AbandonChain(rc) return rc
def doVC(self, res): if self.interrupted: raise AbandonChain(1) if self.sourcedirIsUpdateable() and self.sourcedataMatches(): d = self.doVCUpdate() d.addBoth(self.maybeDoVCFallback) else: d = self.doVCFull() d.addBoth(self.maybeDoVCRetry) d.addCallback(self._abandonOnFailure) d.addCallback(self._handleGotRevision) d.addCallback(self.writeSourcedata) return d
def getCommand(self, name): """Wrapper around utils.getCommand that will output a resonable error message and raise AbandonChain if the command cannot be found""" if name not in self._commandPaths: try: self._commandPaths[name] = utils.getCommand(name) except RuntimeError: self.sendStatus({'stderr': "could not find '%s'\n" % name}) self.sendStatus( {'stderr': "PATH is '%s'\n" % os.environ.get('PATH', '')}) raise AbandonChain(-1) return self._commandPaths[name]
def start(self): # return a Deferred which fires (with the exit code) when the command # completes if self.keepStdout: self.stdout = "" if self.keepStderr: self.stderr = "" self.deferred = defer.Deferred() try: self._startCommand() except Exception: log.err(failure.Failure(), "error in RunProcess._startCommand") self._addToBuffers('stderr', "error in RunProcess._startCommand\n") self._addToBuffers('stderr', traceback.format_exc()) self._sendBuffers() # pretend it was a shell error self.deferred.errback(AbandonChain(-1)) return self.deferred
def maybeDoVCFallback(self, rc): if isinstance(rc, int) and rc == 0: return rc if self.interrupted: raise AbandonChain(1) # allow AssertionErrors to fall through, for benefit of the tests; for # all other errors, carry on to try the fallback if isinstance(rc, failure.Failure) and rc.check(AssertionError): return rc # Let VCS subclasses have an opportunity to handle # unrecoverable errors without having to clobber the repo self.maybeNotDoVCFallback(rc) msg = "update failed, clobbering and trying again" self.sendStatus({'header': msg + "\n"}) log.msg(msg) d = self.doClobber(None, self.srcdir) d.addCallback(self.doVCFallback2) return d
def maybeDoVCRetry(self, res): """We get here somewhere after a VC chain has finished. res could be:: - 0: the operation was successful - nonzero: the operation failed. retry if possible - AbandonChain: the operation failed, someone else noticed. retry. - Failure: some other exception, re-raise """ if isinstance(res, failure.Failure): if self.interrupted: return res # don't re-try interrupted builds res.trap(AbandonChain) else: if isinstance(res, int) and res == 0: return res if self.interrupted: raise AbandonChain(1) # if we get here, we should retry, if possible if self.retry: delay, repeats = self.retry if repeats >= 0: self.retry = (delay, repeats - 1) msg = ("update failed, trying %d more times after %d seconds" % (repeats, delay)) self.sendStatus({'header': msg + "\n"}) log.msg(msg) d = defer.Deferred() # we are going to do a full checkout, so a clobber is # required first self.doClobber(d, self.workdir) if self.srcdir: self.doClobber(d, self.srcdir) d.addCallback(lambda res: self.doVCFull()) d.addBoth(self.maybeDoVCRetry) self._reactor.callLater(delay, d.callback, None) return d return res