+def IsArchitectureSelected(target):
+ def CheckArchitectureProperty(step):
+ try:
+ options = step.getProperty("options")
+ if isinstance(options, dict):
+ selected_arch = options.get("architecture", "all")
+ if selected_arch != "all" and selected_arch != target:
+ return False
+ except KeyError:
+ pass
+
+ return True
+
+ return CheckArchitectureProperty
+
+def UsignSec2Pub(seckey, comment="untrusted comment: secret key"):
+ try:
+ seckey = base64.b64decode(seckey)
+ except Exception:
+ return None
+
+ return "{}\n{}".format(re.sub(r"\bsecret key$", "public key", comment),
+ base64.b64encode(seckey[0:2] + seckey[32:40] + seckey[72:]))
+
+def IsSharedWorkdir(step):
+ return bool(step.getProperty("shared_wd"))
+
+@defer.inlineCallbacks
+def getNewestCompleteTime(bldr):
+ """Returns the complete_at of the latest completed and not SKIPPED
+ build request for this builder, or None if there are no such build
+ requests. We need to filter out SKIPPED requests because we're
+ using collapseRequests=True which is unfortunately marking all
+ previous requests as complete when new buildset is created.
+
+ @returns: datetime instance or None, via Deferred
+ """
+
+ bldrid = yield bldr.getBuilderId()
+ completed = yield bldr.master.data.get(
+ ('builders', bldrid, 'buildrequests'),
+ [
+ resultspec.Filter('complete', 'eq', [True]),
+ resultspec.Filter('results', 'ne', [results.SKIPPED]),
+ ],
+ order=['-complete_at'], limit=1)
+ if not completed:
+ return
+
+ complete_at = completed[0]['complete_at']
+
+ last_build = yield bldr.master.data.get(
+ ('builds', ),
+ [
+ resultspec.Filter('builderid', 'eq', [bldrid]),
+ ],
+ order=['-started_at'], limit=1)
+
+ if last_build and last_build[0]:
+ last_complete_at = last_build[0]['complete_at']
+ if last_complete_at and (last_complete_at > complete_at):
+ return last_complete_at
+
+ return complete_at
+
+@defer.inlineCallbacks
+def prioritizeBuilders(master, builders):
+ """Returns sorted list of builders by their last timestamp of completed and
+ not skipped build.
+
+ @returns: list of sorted builders
+ """
+
+ def is_building(bldr):
+ return bool(bldr.building) or bool(bldr.old_building)
+
+ def bldr_info(bldr):
+ d = defer.maybeDeferred(getNewestCompleteTime, bldr)
+ d.addCallback(lambda complete_at: (complete_at, bldr))
+ return d
+
+ def bldr_sort(item):
+ (complete_at, bldr) = item
+
+ if not complete_at:
+ date = datetime.min
+ complete_at = date.replace(tzinfo=tzutc())
+
+ if is_building(bldr):
+ date = datetime.max
+ complete_at = date.replace(tzinfo=tzutc())
+
+ return (complete_at, bldr.name)
+
+ results = yield defer.gatherResults([bldr_info(bldr) for bldr in builders])
+ results.sort(key=bldr_sort)
+
+ for r in results:
+ log.msg("prioritizeBuilders: {:>20} complete_at: {}".format(r[1].name, r[0]))
+
+ return [r[1] for r in results]
+
+c['prioritizeBuilders'] = prioritizeBuilders