Ejemplo n.º 1
0
def post_pull(extras):
    """Hook executed after client pulls the code."""
    user = User.get_by_username(extras.username)
    action = 'pull'
    action_logger(user, action, extras.repository, extras.ip, commit=True)

    # extension hook call
    post_pull_extension(**extras)

    output = ''
    # make lock is a tri state False, True, None. We only make lock on True
    if extras.make_lock is True:
        Repository.lock(Repository.get_by_repo_name(extras.repository),
                        user.user_id,
                        lock_reason=Repository.LOCK_PULL)
        msg = 'Made lock on repo `%s`' % (extras.repository, )
        output += msg

    if extras.locked_by[0]:
        locked_by = User.get(extras.locked_by[0]).username
        reason = extras.locked_by[2]
        _http_ret = HTTPLockedRC(
            _locked_by_explanation(extras.repository, locked_by, reason))
        if str(_http_ret.code).startswith('2'):
            # 2xx Codes don't raise exceptions
            output += _http_ret.title

    return HookResponse(0, output)
Ejemplo n.º 2
0
def pre_push(extras):
    """
    Hook executed before pushing code.

    It bans pushing when the repository is locked.
    """
    usr = User.get_by_username(extras.username)

    output = ''
    if extras.locked_by[0] and usr.user_id != int(extras.locked_by[0]):
        locked_by = User.get(extras.locked_by[0]).username
        reason = extras.locked_by[2]
        # this exception is interpreted in git/hg middlewares and based
        # on that proper return code is server to client
        _http_ret = HTTPLockedRC(
            _locked_by_explanation(extras.repository, locked_by, reason))
        if str(_http_ret.code).startswith('2'):
            # 2xx Codes don't raise exceptions
            output = _http_ret.title
        else:
            raise _http_ret

    # Calling hooks after checking the lock, for consistent behavior
    pre_push_extension(repo_store_path=Repository.base_path(), **extras)

    return HookResponse(0, output)
Ejemplo n.º 3
0
def log_pull_action(ui, repo, **kwargs):
    """
    Logs user last pull action

    :param ui:
    :param repo:
    """
    ex = _extract_extras()

    user = User.get_by_username(ex.username)
    action = 'pull'
    action_logger(user, action, ex.repository, ex.ip, commit=True)
    # extension hook call
    from rhodecode import EXTENSIONS
    callback = getattr(EXTENSIONS, 'PULL_HOOK', None)
    if isfunction(callback):
        kw = {}
        kw.update(ex)
        callback(**kw)

    if ex.make_lock is not None and ex.make_lock:
        Repository.lock(Repository.get_by_repo_name(ex.repository),
                        user.user_id)
        #msg = 'Made lock on repo `%s`' % repository
        #sys.stdout.write(msg)

    if ex.locked_by[0]:
        locked_by = User.get(ex.locked_by[0]).username
        _http_ret = HTTPLockedRC(ex.repository, locked_by)
        if str(_http_ret.code).startswith('2'):
            #2xx Codes don't raise exceptions
            sys.stdout.write(_http_ret.title)
    return 0
Ejemplo n.º 4
0
def log_push_action(ui, repo, **kwargs):
    """
    Maps user last push action to new changeset id, from mercurial

    :param ui:
    :param repo: repo object containing the `ui` object
    """

    ex = _extract_extras()

    action = ex.action + ':%s'

    if ex.scm == 'hg':
        node = kwargs['node']

        def get_revs(repo, rev_opt):
            if rev_opt:
                revs = revrange(repo, rev_opt)

                if len(revs) == 0:
                    return (nullrev, nullrev)
                return (max(revs), min(revs))
            else:
                return (len(repo) - 1, 0)

        stop, start = get_revs(repo, [node + ':'])
        h = binascii.hexlify
        revs = [h(repo[r].node()) for r in xrange(start, stop + 1)]
    elif ex.scm == 'git':
        revs = kwargs.get('_git_revs', [])
        if '_git_revs' in kwargs:
            kwargs.pop('_git_revs')

    action = action % ','.join(revs)

    action_logger(ex.username, action, ex.repository, ex.ip, commit=True)

    # extension hook call
    from rhodecode import EXTENSIONS
    callback = getattr(EXTENSIONS, 'PUSH_HOOK', None)
    if isfunction(callback):
        kw = {'pushed_revs': revs}
        kw.update(ex)
        callback(**kw)

    if ex.make_lock is not None and not ex.make_lock:
        Repository.unlock(Repository.get_by_repo_name(ex.repository))
        msg = 'Released lock on repo `%s`\n' % ex.repository
        sys.stdout.write(msg)

    if ex.locked_by[0]:
        locked_by = User.get(ex.locked_by[0]).username
        _http_ret = HTTPLockedRC(ex.repository, locked_by)
        if str(_http_ret.code).startswith('2'):
            #2xx Codes don't raise exceptions
            sys.stdout.write(_http_ret.title)

    return 0
Ejemplo n.º 5
0
    def _generate_vcs_response(self, environ, start_response, repo_path,
                               repo_name, extras, action):
        """
        Returns a generator for the response content.

        This method is implemented as a generator, so that it can trigger
        the cache validation after all content sent back to the client. It
        also handles the locking exceptions which will be triggered when
        the first chunk is produced by the underlying WSGI application.
        """
        callback_daemon, extras = self._prepare_callback_daemon(extras)
        config = self._create_config(extras, repo_name)
        log.debug('HOOKS extras is %s', extras)
        app = self._create_wsgi_app(repo_path, repo_name, config)

        try:
            with callback_daemon:
                try:
                    response = app(environ, start_response)
                finally:
                    # This statement works together with the decorator
                    # "initialize_generator" above. The decorator ensures that
                    # we hit the first yield statement before the generator is
                    # returned back to the WSGI server. This is needed to
                    # ensure that the call to "app" above triggers the
                    # needed callback to "start_response" before the
                    # generator is actually used.
                    yield "__init__"

                for chunk in response:
                    yield chunk
        except Exception as exc:
            # TODO: johbo: Improve "translating" back the exception.
            if getattr(exc, '_vcs_kind', None) == 'repo_locked':
                exc = HTTPLockedRC(*exc.args)
                _code = rhodecode.CONFIG.get('lock_ret_code')
                log.debug('Repository LOCKED ret code %s!', (_code, ))
            elif getattr(exc, '_vcs_kind', None) == 'requirement':
                log.debug(
                    'Repository requires features unknown to this Mercurial')
                exc = HTTPRequirementError(*exc.args)
            else:
                raise

            for chunk in exc(environ, start_response):
                yield chunk
        finally:
            # invalidate cache on push
            if action == 'push':
                self._invalidate_cache(repo_name)
Ejemplo n.º 6
0
def pre_pull(ui, repo, **kwargs):
    # pre push function, currently used to ban pushing when
    # repository is locked
    ex = _extract_extras()
    if ex.locked_by[0]:
        locked_by = User.get(ex.locked_by[0]).username
        # this exception is interpreted in git/hg middlewares and based
        # on that proper return code is server to client
        _http_ret = HTTPLockedRC(ex.repository, locked_by)
        if str(_http_ret.code).startswith('2'):
            #2xx Codes don't raise exceptions
            sys.stdout.write(_http_ret.title)
        else:
            raise _http_ret
Ejemplo n.º 7
0
def post_push(extras):
    """Hook executed after user pushes to the repository."""
    action_tmpl = extras.action + ':%s'
    commit_ids = extras.commit_ids[:29000]

    action = action_tmpl % ','.join(commit_ids)
    action_logger(extras.username,
                  action,
                  extras.repository,
                  extras.ip,
                  commit=True)

    # extension hook call
    post_push_extension(repo_store_path=Repository.base_path(),
                        pushed_revs=commit_ids,
                        **extras)

    output = ''
    # make lock is a tri state False, True, None. We only release lock on False
    if extras.make_lock is False:
        Repository.unlock(Repository.get_by_repo_name(extras.repository))
        msg = 'Released lock on repo `%s`\n' % extras.repository
        output += msg

    if extras.locked_by[0]:
        locked_by = User.get(extras.locked_by[0]).username
        reason = extras.locked_by[2]
        _http_ret = HTTPLockedRC(
            _locked_by_explanation(extras.repository, locked_by, reason))
        # TODO: johbo: if not?
        if str(_http_ret.code).startswith('2'):
            # 2xx Codes don't raise exceptions
            output += _http_ret.title

    output += 'RhodeCode: push completed\n'

    return HookResponse(0, output)