Пример #1
0
def test_git_pre_pull():
    extras = {
        'hooks': ['pull'],
        'hooks_uri': 'fake_hook_uri',
    }
    with mock_hook_response(status=1, output='foo'):
        assert hooks.git_pre_pull(extras) == hooks.HookResponse(1, 'foo')
Пример #2
0
def test_git_pre_pull_exception_is_caught():
    extras = {
        'hooks': ['pull'],
        'hooks_uri': 'fake_hook_uri',
    }
    with mock_hook_response(status=2, exception=Exception('foo')):
        assert hooks.git_pre_pull(extras).status == 128
Пример #3
0
def test_git_pre_pull_exception_is_caught():
    extras = {
        'hooks': ['pull'],
        'hooks_uri': 'fake_hook_uri',
    }
    with mock_hook_response(status=2, exception=Exception('foo')):
        assert hooks.git_pre_pull(extras).status == 128
Пример #4
0
def test_git_pre_pull():
    extras = {
        'hooks': ['pull'],
        'hooks_uri': 'fake_hook_uri',
    }
    with mock_hook_response(status=1, output='foo'):
        assert hooks.git_pre_pull(extras) == hooks.HookResponse(1, 'foo')
Пример #5
0
def test_git_pre_pull_is_disabled():
    assert hooks.git_pre_pull({'hooks': ['push']}) == hooks.HookResponse(0, '')
Пример #6
0
    def backend(self, request, environ):
        """
        WSGI Response producer for HTTP POST Git Smart HTTP requests.
        Reads commands and data from HTTP POST's body.
        returns an iterator obj with contents of git command's
        response to stdout
        """
        # TODO(skreft): think how we could detect an HTTPLockedException, as
        # we probably want to have the same mechanism used by mercurial and
        # simplevcs.
        # For that we would need to parse the output of the command looking for
        # some signs of the HTTPLockedError, parse the data and reraise it in
        # pygrack. However, that would interfere with the streaming.
        #
        # Now the output of a blocked push is:
        # Pushing to http://test_regular:[email protected]:5001/vcs_test_git
        # POST git-receive-pack (1047 bytes)
        # remote: ERROR: Repository `vcs_test_git` locked by user `test_admin`. Reason:`lock_auto`
        # To http://test_regular:[email protected]:5001/vcs_test_git
        # ! [remote rejected] master -> master (pre-receive hook declined)
        # error: failed to push some refs to 'http://*****:*****@127.0.0.1:5001/vcs_test_git'

        git_command = self._get_fixedpath(request.path_info)
        if git_command not in self.commands:
            log.debug('command %s not allowed', git_command)
            return exc.HTTPForbidden()

        capabilities = None
        if git_command == 'git-upload-pack':
            capabilities = self._get_want_capabilities(request)

        if 'CONTENT_LENGTH' in environ:
            inputstream = FileWrapper(request.body_file_seekable,
                                      request.content_length)
        else:
            inputstream = request.body_file_seekable

        resp = Response()
        resp.content_type = ('application/x-%s-result' %
                             git_command.encode('utf8'))
        resp.charset = None

        pre_pull_messages = ''
        if git_command == 'git-upload-pack':
            status, pre_pull_messages = hooks.git_pre_pull(self.extras)
            if status != 0:
                resp.app_iter = self._build_failed_pre_pull_response(
                    capabilities, pre_pull_messages)
                return resp

        gitenv = dict(os.environ)
        # forget all configs
        gitenv['GIT_CONFIG_NOGLOBAL'] = '1'
        gitenv['RC_SCM_DATA'] = json.dumps(self.extras)
        cmd = [
            self.git_path, git_command[4:], '--stateless-rpc',
            self.content_path
        ]
        log.debug('handling cmd %s', cmd)

        out = subprocessio.SubprocessIOChunker(cmd,
                                               inputstream=inputstream,
                                               env=gitenv,
                                               cwd=self.content_path,
                                               shell=False,
                                               fail_on_stderr=False,
                                               fail_on_return_code=False)

        if self.update_server_info and git_command == 'git-receive-pack':
            # We need to fully consume the iterator here, as the
            # update-server-info command needs to be run after the push.
            out = list(out)

            # Updating refs manually after each push.
            # This is required as some clients are exposing Git repos internally
            # with the dumb protocol.
            cmd = [self.git_path, 'update-server-info']
            log.debug('handling cmd %s', cmd)
            output = subprocessio.SubprocessIOChunker(
                cmd,
                inputstream=inputstream,
                env=gitenv,
                cwd=self.content_path,
                shell=False,
                fail_on_stderr=False,
                fail_on_return_code=False)
            # Consume all the output so the subprocess finishes
            for _ in output:
                pass

        if git_command == 'git-upload-pack':
            unused_status, post_pull_messages = hooks.git_post_pull(
                self.extras)
            resp.app_iter = self._inject_messages_to_response(
                out, capabilities, pre_pull_messages, post_pull_messages)
        else:
            resp.app_iter = out

        return resp
Пример #7
0
def test_git_pre_pull_is_disabled():
    assert hooks.git_pre_pull({'hooks': ['push']}) == hooks.HookResponse(0, '')
Пример #8
0
    def backend(self, request, environ):
        """
        WSGI Response producer for HTTP POST Git Smart HTTP requests.
        Reads commands and data from HTTP POST's body.
        returns an iterator obj with contents of git command's
        response to stdout
        """
        # TODO(skreft): think how we could detect an HTTPLockedException, as
        # we probably want to have the same mechanism used by mercurial and
        # simplevcs.
        # For that we would need to parse the output of the command looking for
        # some signs of the HTTPLockedError, parse the data and reraise it in
        # pygrack. However, that would interfere with the streaming.
        #
        # Now the output of a blocked push is:
        # Pushing to http://test_regular:[email protected]:5001/vcs_test_git
        # POST git-receive-pack (1047 bytes)
        # remote: ERROR: Repository `vcs_test_git` locked by user `test_admin`. Reason:`lock_auto`
        # To http://test_regular:[email protected]:5001/vcs_test_git
        # ! [remote rejected] master -> master (pre-receive hook declined)
        # error: failed to push some refs to 'http://*****:*****@127.0.0.1:5001/vcs_test_git'

        git_command = self._get_fixedpath(request.path_info)
        if git_command not in self.commands:
            log.debug('command %s not allowed', git_command)
            return exc.HTTPForbidden()

        capabilities = None
        if git_command == 'git-upload-pack':
            capabilities = self._get_want_capabilities(request)

        if 'CONTENT_LENGTH' in environ:
            inputstream = FileWrapper(request.body_file_seekable,
                                      request.content_length)
        else:
            inputstream = request.body_file_seekable

        resp = Response()
        resp.content_type = ('application/x-%s-result' %
                             git_command.encode('utf8'))
        resp.charset = None

        if git_command == 'git-upload-pack':
            status, pre_pull_messages = hooks.git_pre_pull(self.extras)
            if status != 0:
                resp.app_iter = self._build_failed_pre_pull_response(
                    capabilities, pre_pull_messages)
                return resp

        gitenv = dict(os.environ)
        # forget all configs
        gitenv['GIT_CONFIG_NOGLOBAL'] = '1'
        gitenv['RC_SCM_DATA'] = json.dumps(self.extras)
        cmd = [self.git_path, git_command[4:], '--stateless-rpc',
               self.content_path]
        log.debug('handling cmd %s', cmd)

        out = subprocessio.SubprocessIOChunker(
            cmd,
            inputstream=inputstream,
            env=gitenv,
            cwd=self.content_path,
            shell=False,
            fail_on_stderr=False,
            fail_on_return_code=False
        )

        if self.update_server_info and git_command == 'git-receive-pack':
            # We need to fully consume the iterator here, as the
            # update-server-info command needs to be run after the push.
            out = list(out)

            # Updating refs manually after each push.
            # This is required as some clients are exposing Git repos internally
            # with the dumb protocol.
            cmd = [self.git_path, 'update-server-info']
            log.debug('handling cmd %s', cmd)
            output = subprocessio.SubprocessIOChunker(
                cmd,
                inputstream=inputstream,
                env=gitenv,
                cwd=self.content_path,
                shell=False,
                fail_on_stderr=False,
                fail_on_return_code=False
            )
            # Consume all the output so the subprocess finishes
            for _ in output:
                pass

        if git_command == 'git-upload-pack':
            out = list(out)
            unused_status, post_pull_messages = hooks.git_post_pull(self.extras)
            resp.app_iter = self._inject_messages_to_response(
                out, capabilities, pre_pull_messages, post_pull_messages)
        else:
            resp.app_iter = out

        return resp