Beispiel #1
0
 def get_build_info(self, bid):
     # brid, buildername, buildnum
     build_obj = rpc.RpcProxy('software_dev.commit')
     res = build_obj.read(bid, ['buildername', 'build_number'])
     if res:
         return (res['id'], res['buildername'], res['build_number'])
     return (None, None, None)
Beispiel #2
0
    def scheduler_retire_changes(self, schedulerid, changeids, t):
        scha_obj = rpc.RpcProxy('software_dev.sched_change')

        # one time for important ones
        sids = scha_obj.search([('sched_id', '=', schedulerid),
                                ('commit_id', 'in', changeids)])
        res = scha_obj.unlink(sids)
Beispiel #3
0
    def create_buildset(self,
                        ssid,
                        reason,
                        properties,
                        builderNames,
                        t,
                        external_idstring=None):
        # this creates both the BuildSet and the associated BuildRequests
        now = self._getCurrentTime()
        bset_obj = rpc.RpcProxy('software_dev.commit')

        vals = {  # sourcestamp:
            'submitted_at': time2str(now),
        }
        if external_idstring:
            vals['external_idstring'] = external_idstring
        if reason:
            vals['reason'] = reason
        bsid = ssid  # buildset == sourcestamp == change
        bset_obj.write(bsid, vals)
        for propname, propvalue in properties.properties.items():
            bset_obj.setProperties(
                bsid, [(pn, json.dumps(pv))
                       for pn, pv in properties.properties.items()])
        # TODO: respect builderNames
        brids = []
        brid = ssid  # buildrequest == sourcestamp
        brids.append(brid)
        self.notify("add-buildset", bsid)
        self.notify("add-buildrequest", *brids)
        return bsid
Beispiel #4
0
    def getSourceStampNumberedNow(self, ssid, t=None, old_res=None):
        assert isinstance(ssid, (int, long))
        ss = self._sourcestamp_cache.get(ssid)
        if ss:
            return ss

        assert isinstance(ssid, (int, long))
        sstamp_obj = rpc.RpcProxy('software_dev.commit')

        if not old_res:
            res = sstamp_obj.read(ssid)
        else:
            res = old_res
        if not res:
            return None

        branch = None  # res['branch_url']
        revision = res.get('revno', False) or res.get('hash', '')

        patch = None
        #if patchid is not None:
        #    raise NotImplementedError

        changes = None

        changeid = ssid
        changes = [
            self.getChangeNumberedNow(changeid, t),
        ]
        ss = SourceStamp(branch, revision, patch, changes)
        # project=project, repository=repository)
        ss.ssid = ssid
        self._sourcestamp_cache.add(ssid, ss)
        return ss
Beispiel #5
0
 def get_buildnums_for_brid(self, brid):
     build_obj = rpc.RpcProxy('software_dev.commit')
     # remember: buildrequest == build in our schema
     res = build_obj.read(brid, ['build_number'])
     return [
         res['build_number'],
     ]
Beispiel #6
0
    def _get_change_num(self, trans, changeid):
        change_obj = rpc.RpcProxy('software_dev.commit')
        if isinstance(changeid, (list, tuple)):
            cids = changeid
        else:
            cids = [
                changeid,
            ]
        if not cids:
            return []
        res = change_obj.getChanges(cids)

        ret = []
        props = self.get_properties_from_db(change_obj, cids)
        for cdict in res:
            c = OpenObjectChange(**cdict)

            p = props.get(cdict['id'], Properties())
            c.properties.updateFromProperties(p)

            self._change_cache.add(cdict['id'], c)
            ret.append(c)
        if isinstance(changeid, (list, tuple)):
            return ret
        else:
            return ret[0]
Beispiel #7
0
    def saveStatResults(self, changes, file_stats):
        """ Try to save file_stats inside the filechanges of commits
        
        @param changes is the list of changes (as in allChanges() )
        @param file_stats is a dict of { fname:, { lines_add:,  lines_rem: }}
        """

        # commit_obj = rpc.RpcProxy('software_dev.commit')
        fchange_obj = rpc.RpcProxy('software_dev.filechange')

        commit_ids = []
        for chg in changes:
            if not chg.number:
                continue
            commit_ids.append(chg.number)

        while len(commit_ids) and len(file_stats):
            cid = commit_ids.pop()  # so, we attribute the stats to the
            # last commit that matches their files
            fc_ids = fchange_obj.search([('commit_id', '=', cid)])
            fcres = fchange_obj.read(fc_ids, ['filename'])
            # We read all the filenames that belong to the commit and
            # then try to see if we have any stats for them.
            if not fcres:
                continue
            for fcd in fcres:
                fcstat = file_stats.pop(fcd['filename'], False)
                if not fcstat:
                    continue
                # now, we have a filechange.id and stats
                fchange_obj.write(fcd['id'], fcstat)
Beispiel #8
0
    def get_buildername_for_brid(self, brid):
        breq_obj = rpc.RpcProxy('software_dev.commit')

        res = breq_obj.read(brid, ['buildername'])
        if not res:
            return None
        return res['buildername']
Beispiel #9
0
 def _txn_build_started(self, t, brid, buildnumber):
     now = self._getCurrentTime()
     build_obj = rpc.RpcProxy('software_dev.commit')
     vals = {'build_number': buildnumber, 'build_start_time': time2str(now)}
     build_obj.write(brid, vals)
     bid = brid  # one table is used for everything
     self.notify("add-build", bid)
     return bid
Beispiel #10
0
 def scheduler_classify_change(self, schedulerid, number, important, t):
     scha_obj = rpc.RpcProxy('software_dev.sched_change')
     # print "Classify change %s at %s as important=%s" %( number, schedulerid, important)
     scha_obj.create({
         'commit_id': number,
         'sched_id': schedulerid,
         'important': important
     })
Beispiel #11
0
 def removeChangeNow(self, changeid):
     """Thoroughly remove a change from the database, including all dependent
     tables"""
     change_obj = rpc.RpcProxy('software_dev.commit')
     change_obj.unlink([
         changeid,
     ])
     return None
Beispiel #12
0
    def saveTResults(self, build_id, name, build_result, t_results):
        bld_obj = rpc.RpcProxy('software_dev.commit')
        tsum_obj = rpc.RpcProxy('software_dev.test_result')

        for seq, tr in enumerate(t_results):
            vals = {
                'build_id': build_id,
                'name': name,
                'substep': '.'.join(tr.name),  # it is a tuple in TestResult
                'state': res_state.get(tr.results, 'unknown'),
                'sequence': seq,
                'blame_log': tr.text,
            }

            tsum_obj.create(vals)

        return
Beispiel #13
0
    def get_pending_brids_for_builder(self, buildername):
        breq_obj = rpc.RpcProxy('software_dev.commit')

        bids = breq_obj.search([('buildername', '=', buildername),
                                ('complete', '=', False),
                                ('claimed_at', '=', False)])

        return list(bids)
Beispiel #14
0
 def getChangeIdsLessThanIdNow(self, new_changeid):
     """Return a list of all extant change id's less than the given value,
     sorted by number."""
     change_obj = rpc.RpcProxy('software_dev.commit')
     cids = change_obj.search([('id', '<', new_changeid)])
     t = Token()
     changes = self.runInteractionNow(self._get_change_num, cids)
     changes.sort(key=lambda c: c.number)
     return changes
Beispiel #15
0
 def get_buildset_info(self, bsid):
     bset_obj = rpc.RpcProxy('software_dev.commit')
     res = bset_obj.read(
         bsid, ['external_idstring', 'reason', 'complete', 'results'])
     if res:
         external_idstring = res['external_idstring'] or None
         reason = res['reason'] or None
         complete = bool(res['complete'])
         return (external_idstring, reason, bsid, complete, res['results'])
     return None  # shouldn't happen
Beispiel #16
0
 def poll_config(self):
     bbot_obj = rpc.RpcProxy('software_dev.buildbot')
     try:
         new_tstamp = bbot_obj.get_conf_timestamp([
             self.bbot_id,
         ])
         # print "Got conf timestamp:", self.bbot_tstamp
     except Exception, e:
         print "Could not get timestamp: %s" % e
         return
Beispiel #17
0
 def __init__(self, svc, proxy, locals=None, timeout=60 * 5, pre_prompt=''):
     if 0:
         self.proxy = rpc.RpcProxy()
         self.svc = rpc.RpcService()
     self.proxy = proxy
     self.svc = svc
     self.proxy.timeout = timeout
     self.log_hdlr = None
     self.loged = True
     self.pre_prompt = pre_prompt
     self.init(locals)
Beispiel #18
0
 def saveCStats(self, cid, cstats):
     """ Try to save commit stats of change(s)
     
     @param cstats is list of tuples of ( change_id:, { lines_add:,  lines_rem:, ... })
     """
     commit_obj = rpc.RpcProxy('software_dev.commit')
     try:
         commit_obj.saveCStats(cid, cstats)
     except rpc.RpcException, e:
         log.err("Cannot save commit stats: %s" % e)
         return False
Beispiel #19
0
 def _txn_resubmit_buildreqs(self, t, brids):
     # the interrupted build that gets resubmitted will still have the
     # same submitted_at value, so it should be re-started first
     breq_obj = rpc.RpcProxy('software_dev.commit')
     # remember: buildrequest == build in our schema
     vals = {
         'claimed_at': False,
         'claimed_by_name': False,
         'claimed_by_incarnation': False
     }
     breq_obj.write(list(brids), vals)
     self.notify("add-buildrequest", *brids)
Beispiel #20
0
    def getChangesGreaterThan(self, last_changeid, t=None):
        """Return a Deferred that fires with a list of all Change instances
        with numbers greater than the given value, sorted by number. This is
        useful for catching up with everything that's happened since you last
        called this function."""
        assert last_changeid >= 0

        change_obj = rpc.RpcProxy('software_dev.commit')
        cids = change_obj.search([('id', '>', last_changeid)])
        # FIXME: defer
        changes = self.runInteractionNow(self._get_change_num, cids)
        changes.sort(key=lambda c: c.number)
        return changes
Beispiel #21
0
    def addSchedulers(self, added):
        sched_obj = rpc.RpcProxy('software_dev.buildscheduler')
        change_obj = rpc.RpcProxy('software_dev.commit')
        for scheduler in added:
            name = scheduler.name
            assert name

            class_name = "%s.%s" % (scheduler.__class__.__module__,
                                    scheduler.__class__.__name__)

            sids = sched_obj.search([('name', '=', name),
                                     ('class_name', '=', class_name)])
            if sids:
                sid = sids[0]
            else:
                sid = None

            if sid is None:
                # create a new row, with the latest changeid (so it won't try
                # to process all of the old changes) new Schedulers are
                # supposed to ignore pre-existing Changes
                max_ids = change_obj.search([], 0, 1, 'id desc')
                # TODO: really all changes?

                if max_ids:
                    max_changeid = max_ids[0]
                else:
                    max_changeid = 0
                state = scheduler.get_initial_state(max_changeid)
                state_json = json.dumps(state)
                sid = sched_obj.create({
                    'name': name,
                    'class_name': class_name,
                    'state_dic': state_json
                })

            log.msg("scheduler '%s' got id %d" % (scheduler.name, sid))
            scheduler.schedulerid = sid
Beispiel #22
0
    def claim_buildrequests(self,
                            now,
                            master_name,
                            master_incarnation,
                            brids,
                            t=None):
        if not brids:
            return
        breq_obj = rpc.RpcProxy('software_dev.commit')

        vals = {
            'claimed_at': time2str(now),
            'claimed_by_name': master_name,
            'claimed_by_incarnation': master_incarnation,
        }
        breq_obj.write(list(brids), vals)
Beispiel #23
0
    def _txn_addChangeToDatabase(self, t, change):
        change_obj = rpc.RpcProxy('software_dev.commit')
        cdict = change.asDict()
        cleanupDict(cdict)
        for f in cdict['files']:
            cleanupDict(f)
        try:
            change.number = change_obj.submit_change(cdict)
            prop_arr = []
            for propname, propvalue in change.properties.properties.items():
                prop_arr.append((propname, json.dumps(propvalue)))
            if prop_arr:
                change_obj.setProperties(change.number, prop_arr)

            self.notify("add-change", change.number)
        except Exception, e:
            log.err("Cannot add change: %s" % e)
Beispiel #24
0
    def getBuildRequestWithNumber(self, brid, t=None):
        assert isinstance(brid, (int, long))

        breq_obj = rpc.RpcProxy('software_dev.commit')
        res = breq_obj.read(brid)

        if not res:
            return None
        ssid = brid  # short-wire
        ss = self.getSourceStampNumberedNow(ssid, t, res)
        properties = self.get_properties_from_db(breq_obj, brid, t)
        bsid = brid
        br = BuildRequest(res['reason'], ss, res['buildername'], properties)
        br.submittedAt = str2time(res['submitted_at'])
        br.priority = res['priority']
        br.id = brid
        br.bsid = bsid
        return br
Beispiel #25
0
    def scheduler_get_classified_changes(self, schedulerid, t):
        scha_obj = rpc.RpcProxy('software_dev.sched_change')

        # one time for important ones
        sids = scha_obj.search([('sched_id', '=', schedulerid),
                                ('important', '=', True)])
        res = scha_obj.read(sids, ['commit_id'])

        important = self._get_change_num(Token(),
                                         [r['commit_id'][0] for r in res])

        # And one more time for unimportant ones
        sids = scha_obj.search([('sched_id', '=', schedulerid),
                                ('important', '=', False)])
        res = scha_obj.read(sids, ['commit_id'])
        unimportant = self._get_change_num(Token(),
                                           [r['commit_id'][0] for r in res])

        return (important, unimportant)
Beispiel #26
0
    def changeEventGenerator(self,
                             branches=[],
                             categories=[],
                             committers=[],
                             minTime=0):
        change_obj = rpc.RpcProxy('software_dev.commit')
        domain = []

        if branches:
            domain.append(('branch_id', 'in', branches))
        # if categories: Not Implemented yet
        #    domain.append( ('category_id', 'in', categories) )

        if committers:
            domain.append(('comitter_id', 'in', committers))

        rows = change_obj.search(domain, 0, 0, 'id desc')

        changes = self.runInteractionNow(self._get_change_num, rows)
        for chg in changes:
            yield chg
Beispiel #27
0
    def get_unclaimed_buildrequests(self,
                                    buildername,
                                    old,
                                    master_name,
                                    master_incarnation,
                                    t,
                                    limit=None):
        breq_obj = rpc.RpcProxy('software_dev.commit')

        print "Get unclaimed buildrequests for %s after %s" % (buildername,
                                                               time2str(old))
        bids = breq_obj.search(
            [('buildername', '=', buildername),
             ('complete', '=', False), '|', '|', ('claimed_at', '=', False),
             ('claimed_at', '<', time2str(old)), '&',
             ('claimed_by_name', '=', master_name),
             ('claimed_by_incarnation', '!=', master_incarnation)], 0, limit
            or False, 'priority DESC, submitted_at')
        print "Got %d unclaimed buildrequests" % len(bids)
        requests = [self.getBuildRequestWithNumber(bid, t) for bid in bids]
        return requests
Beispiel #28
0
    def _txn_retire_buildreqs(self, t, brids, results):
        now = self._getCurrentTime()
        breq_obj = rpc.RpcProxy('software_dev.commit')
        # remember: buildrequest == build in our schema
        vals = {
            'complete': 1,
            'results': results,
            'complete_at': time2str(now)
        }
        breq_obj.write(brids, vals)

        if True:
            # now, does this cause any buildsets to complete?
            # - Yes, since buildset == buildrequests (still)

            bsids = brids

            t = None
            for bsid in bsids:
                self._check_buildset(t, bsid, now)
        self.notify("retire-buildrequest", *brids)
        self.notify("modify-buildset", *bsids)
Beispiel #29
0
    def _txn_cancel_buildrequest(self, t, brids):
        # TODO: we aren't entirely sure if it'd be safe to just delete the
        # buildrequest: what else might be waiting on it that would then just
        # hang forever?. _check_buildset() should handle it well (an empty
        # buildset will appear complete and SUCCESS-ful). But we haven't
        # thought it through enough to be sure. So for now, "cancel" means
        # "mark as complete and FAILURE".
        now = self._getCurrentTime()
        breq_obj = rpc.RpcProxy('software_dev.commit')
        vals = {
            'complete': True,
            'results': FAILURE,
            'complete_at': time2str(now)
        }
        breq_obj.write(brids, vals)
        # now, does this cause any buildsets to complete?

        bsids = brids
        for bsid in bsids:
            self._check_buildset(t, bsid, now)

        self.notify("cancel-buildrequest", *brids)
        self.notify("modify-buildset", *bsids)
Beispiel #30
0
    def __init__(self, db_props, bmconfig):
        """
            @param db_props a dict with info how to connect to db
            @param c the BuildmasterConfig dict
        """
        log.msg("Keeper config")
        self.bmconfig = bmconfig
        self.poll_interval = 560.0  #seconds
        self.in_reset = False
        self.bbot_tstamp = None
        c = bmconfig
        # some necessary definitions in the dict:
        c['projectName'] = "OpenERP-Test"
        c['buildbotURL'] = "http://test.openobject.com/"
        c['db_url'] = 'openerp://'  # it prevents the db_schema from going SQL
        c['slavePortnum'] = 'tcp:8999:interface=127.0.0.1'

        c['slaves'] = []

        c['schedulers'] = []
        c['builders'] = []
        c['change_source'] = []
        c['status'] = []

        r = rpc.session.login(db_props)
        if r != 0:
            raise Exception("Could not login!")

        bbot_obj = rpc.RpcProxy('software_dev.buildbot')
        bbot_id = bbot_obj.search([('tech_code', '=',
                                    db_props.get('code', 'buildbot'))])
        assert bbot_id, "No buildbot for %r exists!" % db_props.get(
            'code', 'buildbot')
        self.bbot_id = bbot_id[0]
        self.loop = twisted.internet.task.LoopingCall(self.poll_config)

        self.loop.start(self.poll_interval)