def getConfigDict(self): compare_attrs = [] reflect.accumulateClassList( self.__class__, 'compare_attrs', compare_attrs) return {k: getattr(self, k) for k in compare_attrs if hasattr(self, k) and k not in ("passwd", "password")}
def getSpec(self): spec_attributes = [] accumulateClassList(self.__class__, 'spec_attributes', spec_attributes) ret = {} for i in spec_attributes: ret[i] = getattr(self, i) return ret
def _gather_parameters(self): """ Gather options which take a value. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} parameters = [] reflect.accumulateClassList(self.__class__, 'optParameters', parameters) synonyms = {} for parameter in parameters: long, short, default, doc, paramType = util.padTo(5, parameter) if not long: raise ValueError("A parameter cannot be without a name.") docs[long] = doc settings[long] = default if short: shortOpt = shortOpt + short + ':' synonyms[short] = long longOpt.append(long + '=') synonyms[long] = long if paramType is not None: dispatch[long] = CoerceParameter(self, paramType) else: dispatch[long] = CoerceParameter(self, str) return longOpt, shortOpt, docs, settings, synonyms, dispatch
def _startStep_2(self, res): if self.stopped: self.finished(EXCEPTION) return if self.progress: self.progress.start() if isinstance(self.doStepIf, bool): doStep = defer.succeed(self.doStepIf) else: doStep = defer.maybeDeferred(self.doStepIf, self) renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [ doStep ] for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) dl = defer.gatherResults(dl) dl.addCallback(self._startStep_3) return dl
def reconfigServiceWithSibling(self, sibling): # only reconfigure if sibling is configured differently. # sibling == self is using ComparableMixin's implementation # only compare compare_attrs if self.configured and sibling == self: defer.returnValue(None) self.configured = True # render renderables in parallel # Properties import to resolve cyclic import issue from buildbot.process.properties import Properties p = Properties() p.master = self.master # render renderables in parallel secrets = [] kwargs = {} accumulateClassList(self.__class__, 'secrets', secrets) for k, v in sibling._config_kwargs.items(): if k in secrets: value = yield p.render(v) setattr(self, k, value) kwargs.update({k: value}) else: kwargs.update({k: v}) d = yield self.reconfigService(*sibling._config_args, **sibling._config_kwargs) defer.returnValue(d)
def reconfigServiceWithSibling(self, sibling): # only reconfigure if sibling is configured differently. # sibling == self is using ComparableMixin's implementation # only compare compare_attrs if self.configured and sibling == self: return None self.configured = True # render renderables in parallel # Properties import to resolve cyclic import issue from buildbot.process.properties import Properties p = Properties() p.master = self.master # render renderables in parallel secrets = [] kwargs = {} accumulateClassList(self.__class__, 'secrets', secrets) for k, v in sibling._config_kwargs.items(): if k in secrets: # for non reconfigurable services, we force the attribute v = yield p.render(v) setattr(sibling, k, v) setattr(self, k, v) kwargs[k] = v d = yield self.reconfigService(*sibling._config_args, **kwargs) return d
def _gather_flags(self): """ Gather up boolean (flag) options. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} flags = [] reflect.accumulateClassList(self.__class__, 'optFlags', flags) for flag in flags: long, short, doc = util.padTo(3, flag) if not long: raise ValueError("A flag cannot be without a name.") docs[long] = doc settings[long] = 0 if short: shortOpt = shortOpt + short synonyms[short] = long longOpt.append(long) synonyms[long] = long dispatch[long] = self._generic_flag return longOpt, shortOpt, docs, settings, synonyms, dispatch
def __hash__(self): compare_attrs = [] reflect.accumulateClassList( self.__class__, 'compare_attrs', compare_attrs) alist = [self.__class__] + \ [getattr(self, name, self._None) for name in compare_attrs] return hash(tuple(map(str, alist)))
def __init__(self, explorer, rootGroup, canvas): """Place a new Visage of an explorer in a canvas group. I also need a 'canvas' reference is for certain coordinate conversions, and pygnome doesn't give access to my GtkObject's .canvas attribute. :( """ # Ugh. PyGtk/GtkObject/GnomeCanvas interfacing grits. gnome.CanvasGroup.__init__(self, _obj = rootGroup.add('group')._o) self.propertyLabels = PairList() reflect.accumulateClassList(self.__class__, 'propertyLabels', self.propertyLabels) self.groupLabels = PairList() reflect.accumulateClassList(self.__class__, 'groupLabels', self.groupLabels) self.explorer = explorer self.identifier = explorer.identifier self.objectId = explorer.id self.canvas = canvas self.rootGroup = rootGroup self.ebox = gtk.EventBox() self.ebox.set_name("Visage") self.frame = gtk.Frame(self.identifier) self.container = gtk.VBox() self.ebox.add(self.frame) self.frame.add(self.container) self.canvasWidget = self.add('widget', widget=self.ebox, x=0, y=0, anchor=gtk.ANCHOR_NW, size_pixels=0) self.border = self.add('rect', x1=0, y1=0, x2=1, y2=1, fill_color=None, outline_color=self.color['border'], width_pixels=self.border_width) self.subtable = {} self._setup_table() # TODO: # Collapse me # Movable/resizeable me # Destroy me # Set my detail level self.frame.connect("size_allocate", self.signal_size_allocate, None) self.connect("destroy", self.signal_destroy, None) self.connect("event", self.signal_event) self.ebox.show_all()
def _absorbFlags(self): twistd_flags = [] reflect.accumulateClassList(self.__class__, 'optFlags', twistd_flags) for flag in twistd_flags: key = flag[0].replace('-', '_') if hasattr(FLAGS, key): continue flags.DEFINE_boolean(key, None, str(flag[-1]))
def __init__(self, name, **kw): SchemaNode.__init__(self, name) self.elements = list() reflect.accumulateClassList(reflect.getClass(self), 'elements', self.elements) self.attributes = list() reflect.accumulateClassList(reflect.getClass(self), 'attributes', self.attributes) self.__dict__.update(kw)
def GetCommands(steplist): """Extract shell commands from a step. Take the BuildSteps from MockBuild() and, if they inherit from ShellCommand, renders any renderables and extracts out the actual shell command to be executed. Returns a list of command hashes. """ commands = [] for step in steplist: cmdhash = {} StripBuildrunnerIgnore(step) cmdhash['name'] = step.name cmdhash['doStep'] = None cmdhash['stepclass'] = '%s.%s' % (step.__class__.__module__, step.__class__.__name__) if hasattr(step, 'command'): # None signifies this is not a buildrunner-added step. if step.brDoStepIf is None: doStep = step.brDoStepIf # doStep may modify build properties, so it must run before rendering. elif isinstance(step.brDoStepIf, bool): doStep = step.brDoStepIf else: doStep = step.brDoStepIf(step) renderables = [] accumulateClassList(step.__class__, 'renderables', renderables) for renderable in renderables: setattr(step, renderable, step.build.render(getattr(step, renderable))) cmdhash['doStep'] = doStep cmdhash['command'] = step.command cmdhash['quoted_command'] = shell_quote(step.command) cmdhash['workdir'] = step.workdir cmdhash['quoted_workdir'] = shell_quote([step.workdir]) cmdhash['haltOnFailure'] = step.haltOnFailure if hasattr(step, 'env'): cmdhash['env'] = step.env else: cmdhash['env'] = {} if hasattr(step, 'timeout'): cmdhash['timeout'] = step.timeout if hasattr(step, 'maxTime'): cmdhash['maxTime'] = step.maxTime cmdhash['description'] = step.description cmdhash['descriptionDone'] = step.descriptionDone commands.append(cmdhash) return commands
def _absorbParameters(self): twistd_params = [] reflect.accumulateClassList(self.__class__, 'optParameters', twistd_params) for param in twistd_params: key = param[0].replace('-', '_') if hasattr(FLAGS, key): continue if len(param) > 4: flags.DEFINE(FlagParser(param[4]), key, param[2], str(param[3]), serializer=gflags.ArgumentSerializer()) else: flags.DEFINE_string(key, param[2], str(param[3]))
def _getPreprocessors(inst): """ Accumulate elements from the sequences bound at the C{preprocessors} attribute on all classes in the inheritance hierarchy of the class of C{inst}. A C{preprocessors} attribute on the given instance overrides all preprocessors from the class inheritance hierarchy. """ if 'preprocessors' in vars(inst): return inst.preprocessors preprocessors = [] accumulateClassList( inst.__class__, 'preprocessors', preprocessors) return preprocessors
def _cmp_common(self, them): if type(self) != type(them): return (False, None, None) if self.__class__ != them.__class__: return (False, None, None) compare_attrs = [] reflect.accumulateClassList( self.__class__, 'compare_attrs', compare_attrs) self_list = [getattr(self, name, self._None) for name in compare_attrs] them_list = [getattr(them, name, self._None) for name in compare_attrs] return (True, self_list, them_list)
def getRenderingFor(self, props): renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [] for renderable in renderables: d = props.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) dl = defer.gatherResults(dl) dl.addCallback(self.make_command) return dl
def __cmp__(self, them): result = cmp(type(self), type(them)) if result: return result result = cmp(self.__class__, them.__class__) if result: return result compare_attrs = [] reflect.accumulateClassList( self.__class__, 'compare_attrs', compare_attrs) self_list = [getattr(self, name, self._None) for name in compare_attrs] them_list = [getattr(them, name, self._None) for name in compare_attrs] return cmp(self_list, them_list)
def updateDestinguishedName(self, subject): DN = {} parameters = [] reflect.accumulateClassList(self.__class__, 'optParameters', parameters) for parameter in parameters: key, short, val, doc, _type = util.padTo(5, parameter) if self.opts[key]: val = _type and _type(self.opts[key]) or self.opts[key] elif self.defaults[key]: val = _type and _type(self.defaults[key]) or self.defaults[key] if key == 'years': val = 60 * 60 * 24 * 365 * val if val and key in self.x509names: try: setattr(subject, self.x509names.get(key), val.strip()) except crypto.Error, err: raise SysExit("Setting value of '%s' failed: %s", key, err[0][0][2]) DN[self.x509names.get(key)] = val.strip()
def GetCommands(steplist): """Extract shell commands from a step. Take the BuildSteps from MockBuild() and, if they inherit from ShellCommand, renders any renderables and extracts out the actual shell command to be executed. Returns a list of command hashes. """ commands = [] for step in steplist: if hasattr(step, 'command'): cmdhash = {} renderables = [] accumulateClassList(step.__class__, 'renderables', renderables) for renderable in renderables: setattr(step, renderable, step.build.render(getattr(step, renderable))) if isinstance(step.brDoStepIf, bool): doStep = step.brDoStepIf else: doStep = step.brDoStepIf() StripBuildrunnerIgnore(step) cmdhash['name'] = step.name cmdhash['doStep'] = doStep cmdhash['command'] = step.command cmdhash['quoted_command'] = shell_quote(step.command) cmdhash['workdir'] = step.workdir cmdhash['quoted_workdir'] = shell_quote([step.workdir]) if hasattr(step, 'env'): cmdhash['env'] = step.env else: cmdhash['env'] = {} if hasattr(step, 'timeout'): cmdhash['timeout'] = step.timeout cmdhash['description'] = step.description cmdhash['descriptionDone'] = step.descriptionDone commands.append(cmdhash) return commands
def _startStep_2(self, res): if self.stopped: self.finished(EXCEPTION) return if self.progress: self.progress.start() if isinstance(self.doStepIf, bool): doStep = defer.succeed(self.doStepIf) else: doStep = defer.maybeDeferred(self.doStepIf, self) renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) for renderable in renderables: setattr(self, renderable, self.build.render(getattr(self, renderable))) doStep.addCallback(self._startStep_3) return doStep
def _gather_parameters(self): """ Gather options which take a value. """ longOpt, shortOpt = [], '' docs, settings, synonyms, dispatch = {}, {}, {}, {} parameters = [] reflect.accumulateClassList(self.__class__, 'optStrings', parameters) if parameters: import warnings warnings.warn( "Options.optStrings is deprecated, " "please use optParameters instead.", stacklevel=2) reflect.accumulateClassList(self.__class__, 'optParameters', parameters) synonyms = {} for parameter in parameters: long, short, default, doc, paramType = util.padTo(5, parameter) if not long: raise ValueError("A parameter cannot be without a name.") docs[long] = doc settings[long] = default if short: shortOpt = shortOpt + short + ':' synonyms[short] = long longOpt.append(long + '=') synonyms[long] = long if paramType is not None: dispatch[long] = CoerceParameter(self, paramType) else: dispatch[long] = CoerceParameter(self, str) return longOpt, shortOpt, docs, settings, synonyms, dispatch
def _set_defaults(self, parser, subCommands): parser_defaults = parser.defaults() for name, sname, options, doc in subCommands: if hasattr(options, 'optParameters'): parameters = [] instance = options().__class__ reflect.accumulateClassList(instance, 'optParameters', parameters) for idx, parameter in enumerate(parameters): long, short, default, doc, type = util.padTo(5, parameter) _def = parser_defaults.get(long, default) if parser.has_option(name, long): _def = parser.get(name, long, _def) if _def != default: option = [long, short, type and type(_def) or _def, doc] if type: option.append(type) parameters[idx] = option # Override class defaults with config-file defaults options.optParameters = parameters if hasattr(options, "subCommands"): self._set_defaults(parser, options.subCommands)
def gatherDoStepIfResults(self, callback, setRender=True): dl = [] if isinstance(self.doStepIf, list): for func in self.doStepIf: doStep = self.getDoStepIfDefer(func) dl.append(doStep) else: dl = [self.getDoStepIfDefer(self.doStepIf)] if setRender: renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) dl = defer.gatherResults(dl) dl.addCallback(callback) return dl
def __init__(self, object, identifier): self.object = object self.identifier = identifier self.id = id(object) self.properties = [] reflect.accumulateClassList(self.__class__, "properties", self.properties) self.attributeGroups = [] reflect.accumulateClassList(self.__class__, "attributeGroups", self.attributeGroups) self.accessors = [] reflect.accumulateClassList(self.__class__, "accessors", self.accessors)
def __init__(self, object, identifier): self.object = object self.identifier = identifier self.id = id(object) self.properties = [] reflect.accumulateClassList(self.__class__, 'properties', self.properties) self.attributeGroups = [] reflect.accumulateClassList(self.__class__, 'attributeGroups', self.attributeGroups) self.accessors = [] reflect.accumulateClassList(self.__class__, 'accessors', self.accessors)
def getConfigDict(self): compare_attrs = [] reflect.accumulateClassList(self.__class__, 'compare_attrs', compare_attrs) return dict([(k, getattr(self, k)) for k in compare_attrs if hasattr(self, k) and k not in ("passwd", "password")])
from twisted.python import reflect class B1(object): joke = ["hi 1"] class B2(object): joke = ["hi 2"] class B3(object): joke = ["hi 3"] class D(B1, B2, B3): joke = ["hi 4"] l = [] reflect.accumulateClassList(D, 'joke', l) print l
def startStep(self, remote): self.remote = remote self.deferred = defer.Deferred() # convert all locks into their real form self.locks = [(self.build.builder.botmaster.getLockByID(access.lockid), access) for access in self.locks] # then narrow SlaveLocks down to the slave that this build is being # run on self.locks = [(l.getLock(self.build.slavebuilder.slave), la) for l, la in self.locks] for l, la in self.locks: if l in self.build.locks: log.msg("Hey, lock %s is claimed by both a Step (%s) and the" " parent Build (%s)" % (l, self, self.build)) raise RuntimeError("lock claimed by both Step and Build") # Set the step's text here so that the stepStarted notification sees # the correct description self.step_status.setText(self.describe(False)) self.step_status.stepStarted() try: # set up locks yield self.acquireLocks() if self.stopped: self.finished(EXCEPTION) defer.returnValue((yield self.deferred)) # ste up progress if self.progress: self.progress.start() # check doStepIf if isinstance(self.doStepIf, bool): doStep = self.doStepIf else: doStep = yield self.doStepIf(self) # render renderables in parallel renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [] for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) yield defer.gatherResults(dl) try: if doStep: result = yield defer.maybeDeferred(self.start) if result == SKIPPED: doStep = False except: log.msg("BuildStep.startStep exception in .start") self.failed(Failure()) if not doStep: self.step_status.setText(self.describe(True) + ['skipped']) self.step_status.setSkipped(True) # this return value from self.start is a shortcut to finishing # the step immediately; we skip calling finished() as # subclasses may have overridden that an expect it to be called # after start() (bug #837) eventually(self._finishFinished, SKIPPED) except Exception: self.failed(Failure()) # and finally, wait for self.deferred to get triggered and return its # value defer.returnValue((yield self.deferred))
def startStep(self, remote): self.remote = remote # create and start the step, noting that the name may be altered to # ensure uniqueness # XXX self.number != self.step_status.number.. self.stepid, self.number, self.name = yield self.master.data.updates.newStep( buildid=self.build.buildid, name=util.ascii2unicode(self.name)) yield self.master.data.updates.startStep(self.stepid) # convert all locks into their real form self.locks = [(self.build.builder.botmaster.getLockFromLockAccess(access), access) for access in self.locks] # then narrow SlaveLocks down to the slave that this build is being # run on self.locks = [(l.getLock(self.build.slavebuilder.slave), la) for l, la in self.locks] for l, la in self.locks: if l in self.build.locks: log.msg("Hey, lock %s is claimed by both a Step (%s) and the" " parent Build (%s)" % (l, self, self.build)) raise RuntimeError("lock claimed by both Step and Build") self.step_status.stepStarted() try: # set up locks yield self.acquireLocks() if self.stopped: raise BuildStepCancelled # set up progress if self.progress: self.progress.start() # check doStepIf if isinstance(self.doStepIf, bool): doStep = self.doStepIf else: doStep = yield self.doStepIf(self) # render renderables in parallel renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [] for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) yield defer.gatherResults(dl) self.rendered = True # we describe ourselves only when renderables are interpolated self.updateSummary() # run -- or skip -- the step if doStep: try: self._running = True results = yield self.run() finally: self._running = False else: self.step_status.setSkipped(True) results = SKIPPED except BuildStepCancelled: results = CANCELLED except BuildStepFailed: results = FAILURE # fall through to the end except error.ConnectionLost: results = RETRY except Exception: why = Failure() log.err(why, "BuildStep.failed; traceback follows") yield self.addLogWithFailure(why) results = EXCEPTION if self.stopped and results != RETRY: # We handle this specially because we don't care about # the return code of an interrupted command; we know # that this should just be exception due to interrupt # At the same time we must respect RETRY status because it's used # to retry interrupted build due to some other issues for example # due to slave lost if results != CANCELLED: results = EXCEPTION # update the summary one last time, make sure that completes, # and then don't update it any more. self.updateSummary() yield self.updateSummary.stop() if self.progress: self.progress.finish() self.step_status.stepFinished(results) yield self.master.data.updates.finishStep(self.stepid, results) hidden = self.hideStepIf if callable(hidden): try: hidden = hidden(results, self) except Exception: results = EXCEPTION hidden = False self.step_status.setHidden(hidden) self.releaseLocks() defer.returnValue(results)
def startStep(self, remote): self.remote = remote yield self.addStep() self.locks = yield self.build.render(self.locks) # convert all locks into their real form self.locks = [ (self.build.builder.botmaster.getLockFromLockAccess(access), access) for access in self.locks ] # then narrow WorkerLocks down to the worker that this build is being # run on self.locks = [(l.getLock(self.build.workerforbuilder.worker), la) for l, la in self.locks] for l, la in self.locks: if l in self.build.locks: log.msg("Hey, lock %s is claimed by both a Step (%s) and the" " parent Build (%s)" % (l, self, self.build)) raise RuntimeError("lock claimed by both Step and Build") try: # set up locks yield self.acquireLocks() if self.stopped: raise BuildStepCancelled # render renderables in parallel renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [] for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) yield defer.gatherResults(dl) self.rendered = True # we describe ourselves only when renderables are interpolated self.realUpdateSummary() # check doStepIf (after rendering) if isinstance(self.doStepIf, bool): doStep = self.doStepIf else: doStep = yield self.doStepIf(self) # run -- or skip -- the step if doStep: try: self._running = True self.results = yield self.run() finally: self._running = False else: self.results = SKIPPED # NOTE: all of these `except` blocks must set self.results immediately! except BuildStepCancelled: self.results = CANCELLED except BuildStepFailed: self.results = FAILURE except error.ConnectionLost: self.results = RETRY except Exception: self.results = EXCEPTION why = Failure() log.err(why, "BuildStep.failed; traceback follows") yield self.addLogWithFailure(why) if self.stopped and self.results != RETRY: # We handle this specially because we don't care about # the return code of an interrupted command; we know # that this should just be exception due to interrupt # At the same time we must respect RETRY status because it's used # to retry interrupted build due to some other issues for example # due to worker lost if self.results != CANCELLED: self.results = EXCEPTION # update the summary one last time, make sure that completes, # and then don't update it any more. self.realUpdateSummary() yield self.realUpdateSummary.stop() # determine whether we should hide this step hidden = self.hideStepIf if callable(hidden): try: hidden = hidden(self.results, self) except Exception: why = Failure() log.err(why, "hidden callback failed; traceback follows") yield self.addLogWithFailure(why) self.results = EXCEPTION hidden = False yield self.master.data.updates.finishStep(self.stepid, self.results, hidden) # finish unfinished logs all_finished = yield self.finishUnfinishedLogs() if not all_finished: self.results = EXCEPTION self.releaseLocks() defer.returnValue(self.results)
def __init__(self, explorer, rootGroup, canvas): """Place a new Visage of an explorer in a canvas group. I also need a 'canvas' reference is for certain coordinate conversions, and pygnome doesn't give access to my GtkObject's .canvas attribute. :( """ # Ugh. PyGtk/GtkObject/GnomeCanvas interfacing grits. gnome.CanvasGroup.__init__(self, _obj=rootGroup.add('group')._o) self.propertyLabels = PairList() reflect.accumulateClassList(self.__class__, 'propertyLabels', self.propertyLabels) self.groupLabels = PairList() reflect.accumulateClassList(self.__class__, 'groupLabels', self.groupLabels) self.explorer = explorer self.identifier = explorer.identifier self.objectId = explorer.id self.canvas = canvas self.rootGroup = rootGroup self.ebox = gtk.EventBox() self.ebox.set_name("Visage") self.frame = gtk.Frame(self.identifier) self.container = gtk.VBox() self.ebox.add(self.frame) self.frame.add(self.container) self.canvasWidget = self.add('widget', widget=self.ebox, x=0, y=0, anchor=gtk.ANCHOR_NW, size_pixels=0) self.border = self.add('rect', x1=0, y1=0, x2=1, y2=1, fill_color=None, outline_color=self.color['border'], width_pixels=self.border_width) self.subtable = {} self._setup_table() # TODO: # Collapse me # Movable/resizeable me # Destroy me # Set my detail level self.frame.connect("size_allocate", self.signal_size_allocate, None) self.connect("destroy", self.signal_destroy, None) self.connect("event", self.signal_event) self.ebox.show_all()
def startStep(self, remote): self.remote = remote # create and start the step, noting that the name may be altered to # ensure uniqueness self.stepid, self.number, self.name = yield self.master.data.updates.addStep( buildid=self.build.buildid, name=util.ascii2unicode(self.name)) yield self.master.data.updates.startStep(self.stepid) self.locks = yield self.build.render(self.locks) # convert all locks into their real form self.locks = [(self.build.builder.botmaster.getLockFromLockAccess(access), access) for access in self.locks] # then narrow WorkerLocks down to the worker that this build is being # run on self.locks = [(l.getLock(self.build.workerforbuilder.worker), la) for l, la in self.locks] for l, la in self.locks: if l in self.build.locks: log.msg("Hey, lock %s is claimed by both a Step (%s) and the" " parent Build (%s)" % (l, self, self.build)) raise RuntimeError("lock claimed by both Step and Build") try: # set up locks yield self.acquireLocks() if self.stopped: raise BuildStepCancelled # check doStepIf if isinstance(self.doStepIf, bool): doStep = self.doStepIf else: doStep = yield self.doStepIf(self) # render renderables in parallel renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [] for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) yield defer.gatherResults(dl) self.rendered = True # we describe ourselves only when renderables are interpolated self.realUpdateSummary() # run -- or skip -- the step if doStep: try: self._running = True self.results = yield self.run() finally: self._running = False else: self.results = SKIPPED # NOTE: all of these `except` blocks must set self.results immediately! except BuildStepCancelled: self.results = CANCELLED except BuildStepFailed: self.results = FAILURE except error.ConnectionLost: self.results = RETRY except Exception: self.results = EXCEPTION why = Failure() log.err(why, "BuildStep.failed; traceback follows") yield self.addLogWithFailure(why) if self.stopped and self.results != RETRY: # We handle this specially because we don't care about # the return code of an interrupted command; we know # that this should just be exception due to interrupt # At the same time we must respect RETRY status because it's used # to retry interrupted build due to some other issues for example # due to worker lost if self.results != CANCELLED: self.results = EXCEPTION # update the summary one last time, make sure that completes, # and then don't update it any more. self.realUpdateSummary() yield self.realUpdateSummary.stop() # determine whether we should hide this step hidden = self.hideStepIf if callable(hidden): try: hidden = hidden(self.results, self) except Exception: why = Failure() log.err(why, "hidden callback failed; traceback follows") yield self.addLogWithFailure(why) self.results = EXCEPTION hidden = False yield self.master.data.updates.finishStep(self.stepid, self.results, hidden) # finish unfinished logs all_finished = yield self.finishUnfinishedLogs() if not all_finished: self.results = EXCEPTION self.releaseLocks() defer.returnValue(self.results)
def _absorbParameters(self): twistd_params = [] reflect.accumulateClassList(self.__class__, 'optParameters', twistd_params) for param in twistd_params: key = param[0].replace('-', '_') flags.DEFINE_string(key, param[2], str(param[-1]))
def startStep(self, remote): self.remote = remote isNew = self.isNewStyle() old_finished = self.finished old_failed = self.failed if isNew: def nope(*args, **kwargs): raise AssertionError("new-style steps must not call " "this method") self.finished = nope self.failed = nope # convert all locks into their real form self.locks = [ (self.build.builder.botmaster.getLockFromLockAccess(access), access) for access in self.locks ] # then narrow SlaveLocks down to the slave that this build is being # run on self.locks = [(l.getLock(self.build.slavebuilder.slave), la) for l, la in self.locks] for l, la in self.locks: if l in self.build.locks: log.msg("Hey, lock %s is claimed by both a Step (%s) and the" " parent Build (%s)" % (l, self, self.build)) raise RuntimeError("lock claimed by both Step and Build") self.deferred = defer.Deferred() # Set the step's text here so that the stepStarted notification sees # the correct description self._step_status.setText(self.describe(False)) self._step_status.stepStarted() self.build.build_status.build_output = str( self.build.builder.config.builddir ) + '/build/output/build-%s' % self.build.build_status.number try: # set up locks yield self.acquireLocks() if self.stopped: old_finished(EXCEPTION) defer.returnValue((yield self.deferred)) # ste up progress if self.progress: self.progress.start() # check doStepIf if isinstance(self.doStepIf, bool): doStep = self.doStepIf else: doStep = yield self.doStepIf(self) # render renderables in parallel renderables = [] accumulateClassList(self.__class__, 'renderables', renderables) def setRenderable(res, attr): setattr(self, attr, res) dl = [] for renderable in renderables: d = self.build.render(getattr(self, renderable)) d.addCallback(setRenderable, renderable) dl.append(d) yield defer.gatherResults(dl) try: if doStep: if isNew: result = yield self.run() assert isinstance(result, int), \ "run must return an integer (via Deferred)" old_finished(result) else: result = yield self.start() if result == SKIPPED: doStep = False except Exception: log.msg("BuildStep.startStep exception in .start") self.finished = old_finished old_failed(Failure()) if not doStep: self._step_status.setText(self.describe(True) + ['skipped']) self._step_status.setSkipped(True) # this return value from self.start is a shortcut to finishing # the step immediately; we skip calling finished() as # subclasses may have overridden that an expect it to be called # after start() (bug #837) eventually(self._finishFinished, SKIPPED) except Exception: self.finished = old_finished old_failed(Failure()) # and finally, wait for self.deferred to get triggered and return its # value defer.returnValue((yield self.deferred))
def _absorbFlags(self): twistd_flags = [] reflect.accumulateClassList(self.__class__, 'optFlags', twistd_flags) for flag in twistd_flags: key = flag[0].replace('-', '_') flags.DEFINE_boolean(key, None, str(flag[-1]))