Exemple #1
0
    def _response_get_change(self, s, mid, msg, rstate):
        lstate = self.socket[s][Response][rstate['ref']]
        changeset = msg['changeset']
        del msg['changeset']
        if sha.new(changeset).digest() != rstate['changenum']:
            self._close(s)
            return
        write_changeset(self, rstate['changenum'], changeset, lstate['txn'])
        changeset = bdecode(changeset)
        lstate['changes'][rstate['changenum']] = changeset
        for change in changeset['precursors']:
            if self.lcrepo.has_key(change):
                continue
            if lstate['changes'].has_key(change):
                continue
            if lstate['requests'].has_key(change):
                continue
            rid = self._get_change(s, lstate, change)
            self.socket[s][Request][rid] = {
                'request': 'get change',
                'changenum': change,
                'ref': rstate['ref']
            }
            lstate['count'] += 1
        lstate['count'] -= 1
        del self.socket[s][Request][mid]

        # record all the diffs we'll need to request
        diffs = lstate['diffs']
        for handle, hinfo in changeset['handles'].items():
            if not hinfo.has_key('hash'):
                continue
            if not diffs.has_key(handle):
                diffs[handle] = {}
                lstate['counts'][handle] = 0
            diffs[handle][rstate['changenum']] = 1
            lstate['counts'][handle] += 1
        changeset = None

        try:
            if lstate['count'] == 0:
                self._commit_phase_1(s, rstate['ref'])

            if lstate['count'] == 0:
                self._commit_phase_2(s, rstate['ref'])
        except HistoryError, msg:
            self._commit_fail(s, rstate['ref'], str(msg))
            return
Exemple #2
0
    def _response_get_change(self, s, mid, msg, rstate):
        lstate = self.socket[s][Response][rstate['ref']]
        changeset = msg['changeset']
        del msg['changeset']
        if sha.new(changeset).digest() != rstate['changenum']:
            self._close(s)
            return
        write_changeset(self, rstate['changenum'], changeset, lstate['txn'])
        changeset = bdecode(changeset)
        lstate['changes'][rstate['changenum']] = changeset
        for change in changeset['precursors']:
            if self.lcrepo.has_key(change):
                continue
            if lstate['changes'].has_key(change):
                continue
            if lstate['requests'].has_key(change):
                continue
            rid = self._get_change(s, lstate, change)
            self.socket[s][Request][rid] = {'request': 'get change',
                                            'changenum': change,
                                            'ref': rstate['ref']}
            lstate['count'] += 1
        lstate['count'] -= 1
        del self.socket[s][Request][mid]

        # record all the diffs we'll need to request
        diffs = lstate['diffs']
        for handle, hinfo in changeset['handles'].items():
            if not hinfo.has_key('hash'):
                continue
            if not diffs.has_key(handle):
                diffs[handle] = {}
                lstate['counts'][handle] = 0
            diffs[handle][rstate['changenum']] = 1
            lstate['counts'][handle] += 1
        changeset = None

        try:
            if lstate['count'] == 0:
                self._commit_phase_1(s, rstate['ref'])

            if lstate['count'] == 0:
                self._commit_phase_2(s, rstate['ref'])
        except HistoryError, msg:
            self._commit_fail(s, rstate['ref'], str(msg))
            return
Exemple #3
0
    def _response_get_change(self, s, mid, msg, rstate):
        lstate = self.socket[s][Request][rstate['ref']]
        if sha.new(msg['changeset']).digest() != rstate['changenum']:
            raise ServerError, 'bad changeset'

        # write it out, decode and eject from memory
        write_changeset(self.co, rstate['changenum'], msg['changeset'],
                        lstate['txn'])
        changeset = bdecode(msg['changeset'])
        lstate['changes'][rstate['changenum']] = changeset
        del msg['changeset']

        # get any precursors we don't have and haven't yet requested
        for change in changeset['precursors']:
            if self.co.lcrepo.has_key(change):
                continue
            if lstate['changes'].has_key(change):
                continue
            if lstate['requests'].has_key(change):
                continue
            rid = self._get_change(s, change)
            self.socket[s][Request][rid] = {'request': 'get change',
                                            'changenum': change,
                                            'ref': rstate['ref']}
            lstate['requests'][change] = 1
            lstate['count'] += 1

        # record all the diffs we'll need to request
        diffs = lstate['diffs']
        for handle, hinfo in changeset['handles'].items():
            if not hinfo.has_key('hash'):
                continue
            if not diffs.has_key(handle):
                diffs[handle] = {}
                lstate['counts'][handle] = 0
            diffs[handle][rstate['changenum']] = 1
            lstate['counts'][handle] += 1

        # clean up state
        del lstate['requests'][rstate['changenum']]
        lstate['count'] -= 1
        if lstate['count'] == 0:
            sync_history(self.co, lstate['head'], lstate['txn'],
                                    cache=lstate['changes'])
            named, modified, added, deleted = \
                   handles_in_branch(self.co,
                                     lstate['heads'], [lstate['head']],
                                     lstate['txn'], cache=lstate['changes'])
            del lstate['changes']
            self._update_checks(s, rstate['ref'], named, modified)
            self._update_handle_list(s, lstate, named, modified, added, deleted)

            handle_list = lstate['handle list']
            # get all the related file diffs
            for i in xrange(len(handle_list)-1, -1, -1):
                handle = handle_list[i][1]
                if not diffs.has_key(handle):
                    continue
                changes = diffs[handle]

                requested = 0
                for change in changes.keys():
                    requested = 1
                    self._queue_diff(s, change, handle, rstate['ref'])
                lstate['count'] += requested
            self._get_diff(s, rstate['ref'])

        if lstate['count'] == 0:
            self._update_finish(s, lstate)
            del self.socket[s][Request][rstate['ref']]
            self.rs.doneflag.set()
        return 1
Exemple #4
0
    def _commit_phase_2(self, s, mid):
        request = self.socket[s][Response][mid]
        txn = request['txn']
        head = request['cur head']

        if request.has_key('no phase 2'):
            self.txn_commit(txn)
            del self.socket[s][Response][mid]
            self._send_response(s, mid, {})
            return

        # backup servers don't create clean merge heads
        req_head = request['head']
        if not self.config.getboolean('control', 'backup'):
            # create new clean merge head
            changeset = bencode({
                'precursors': [head, req_head],
                'user': self.socket[s][User],
                'time': int(time()),
                'handles': {}
            })
            new_head = request['new head'] = sha.new(changeset).digest()
            write_changeset(self, new_head, changeset, txn)
        else:
            new_head = request['head']

        self.repolistdb.put(request['repository'], new_head, txn=txn)
        sync_history(self, new_head, txn, cache=request['changes'])
        del request['changes']

        # validate all the files for which we already have the diffs
        locks = []
        for handle, checked in request['modified'].items():
            locks.append(handle)

            # did we already validate it?
            if checked:
                continue

            # if there are diffs then some other checkin verified them
            # we only need to make sure there aren't any implicit merges
            handle_merge_check(self, handle, new_head, txn)

        # complete everything and clean up
        self.txn_commit(txn)
        del self.socket[s][Response][mid]
        self._send_response(s, mid, {})

        for handle in locks:
            self._unlock_file(s, handle)

        for pattern, action in self.post_commit:
            if not pattern.search(request['repository']):
                continue

            try:
                afd = os.popen(action, 'w')
                afd.write(
                    dump_changeinfo(self, new_head,
                                    repo=request['repository']))
                afd.close()
            except IOError, msg:
                print 'Command failed'
                print 'Command: ' + action
                print 'Error: ' + str(msg)
Exemple #5
0
    def _commit_phase_2(self, s, mid):
        request = self.socket[s][Response][mid]
        txn = request['txn']
        head = request['cur head']

        if request.has_key('no phase 2'):
            self.txn_commit(txn)
            del self.socket[s][Response][mid]
            self._send_response(s, mid, {})
            return

        # backup servers don't create clean merge heads
        req_head = request['head']
        if not self.config.getboolean('control', 'backup'):
            # create new clean merge head
            changeset = bencode({'precursors': [head, req_head],
                                 'user': self.socket[s][User],
                                 'time': int(time()),
                                 'handles': {}})
            new_head = request['new head'] = sha.new(changeset).digest()
            write_changeset(self, new_head, changeset, txn)
        else:
            new_head = request['head']

        self.repolistdb.put(request['repository'], new_head, txn=txn)
        sync_history(self, new_head, txn, cache=request['changes'])
        del request['changes']

        # validate all the files for which we already have the diffs
        locks = []
        for handle, checked in request['modified'].items():
            locks.append(handle)

            # did we already validate it?
            if checked:
                continue

            # if there are diffs then some other checkin verified them
            # we only need to make sure there aren't any implicit merges
            handle_merge_check(self, handle, new_head, txn)

        # complete everything and clean up
        self.txn_commit(txn)
        del self.socket[s][Response][mid]
        self._send_response(s, mid, {})

        for handle in locks:
            self._unlock_file(s, handle)

        for pattern, action in self.post_commit:
            if not pattern.search(request['repository']):
                continue

            try:
                afd = os.popen(action, 'w')
                afd.write(dump_changeinfo(self, new_head, repo=request['repository']))
                afd.close()
            except IOError, msg:
                print 'Command failed'
                print 'Command: ' + action
                print 'Error: ' + str(msg)
Exemple #6
0
    def _response_get_change(self, s, mid, msg, rstate):
        lstate = self.socket[s][Request][rstate['ref']]
        if sha.new(msg['changeset']).digest() != rstate['changenum']:
            raise ServerError, 'bad changeset'

        # write it out, decode and eject from memory
        write_changeset(self.co, rstate['changenum'], msg['changeset'],
                        lstate['txn'])
        changeset = bdecode(msg['changeset'])
        lstate['changes'][rstate['changenum']] = changeset
        del msg['changeset']

        # get any precursors we don't have and haven't yet requested
        for change in changeset['precursors']:
            if self.co.lcrepo.has_key(change):
                continue
            if lstate['changes'].has_key(change):
                continue
            if lstate['requests'].has_key(change):
                continue
            rid = self._get_change(s, change)
            self.socket[s][Request][rid] = {
                'request': 'get change',
                'changenum': change,
                'ref': rstate['ref']
            }
            lstate['requests'][change] = 1
            lstate['count'] += 1

        # record all the diffs we'll need to request
        diffs = lstate['diffs']
        for handle, hinfo in changeset['handles'].items():
            if not hinfo.has_key('hash'):
                continue
            if not diffs.has_key(handle):
                diffs[handle] = {}
                lstate['counts'][handle] = 0
            diffs[handle][rstate['changenum']] = 1
            lstate['counts'][handle] += 1

        # clean up state
        del lstate['requests'][rstate['changenum']]
        lstate['count'] -= 1
        if lstate['count'] == 0:
            sync_history(self.co,
                         lstate['head'],
                         lstate['txn'],
                         cache=lstate['changes'])
            named, modified, added, deleted = \
                   handles_in_branch(self.co,
                                     lstate['heads'], [lstate['head']],
                                     lstate['txn'], cache=lstate['changes'])
            del lstate['changes']
            self._update_checks(s, rstate['ref'], named, modified)
            self._update_handle_list(s, lstate, named, modified, added,
                                     deleted)

            handle_list = lstate['handle list']
            # get all the related file diffs
            for i in xrange(len(handle_list) - 1, -1, -1):
                handle = handle_list[i][1]
                if not diffs.has_key(handle):
                    continue
                changes = diffs[handle]

                requested = 0
                for change in changes.keys():
                    requested = 1
                    self._queue_diff(s, change, handle, rstate['ref'])
                lstate['count'] += requested
            self._get_diff(s, rstate['ref'])

        if lstate['count'] == 0:
            self._update_finish(s, lstate)
            del self.socket[s][Request][rstate['ref']]
            self.rs.doneflag.set()
        return 1