Exemplo n.º 1
0
    def _get_pr_files(self, repo, number):
        """
        Get Files that belong to the Pull Request
        :param repo: the repo full name, ``{owner}/{project}``.
            e.g. ``buildbot/buildbot``
        :param number: the pull request number.
        """
        headers = {"User-Agent": "Buildbot"}
        if self._token:
            p = Properties()
            p.master = self.master
            token = yield p.render(self._token)
            headers["Authorization"] = "token " + token

        url = f"/repos/{repo}/pulls/{number}/files"
        http = yield httpclientservice.HTTPClientService.getService(
            self.master,
            self.github_api_endpoint,
            headers=headers,
            debug=self.debug,
            verify=self.verify,
        )
        res = yield http.get(url)
        if 200 <= res.code < 300:
            data = yield res.json()
            return [f["filename"] for f in data]

        log.msg(f'Failed fetching PR files: response code {res.code}')
        return []
Exemplo n.º 2
0
    def _downloadSshPrivateKeyIfNeeded(self):
        if self.sshPrivateKey is None:
            defer.returnValue(RC_SUCCESS)

        p = Properties()
        p.master = self.master
        private_key = yield p.render(self.sshPrivateKey)
        host_key = yield p.render(self.sshHostKey)

        # not using self.workdir because it may be changed depending on step
        # options
        workdir = self._getSshDataWorkDir()

        yield self.runMkdir(self._getSshDataPath())

        if not self.supportsSshPrivateKeyAsEnvOption:
            yield self.downloadFileContentToWorker(self._getSshWrapperScriptPath(),
                                                   self._getSshWrapperScript(),
                                                   workdir=workdir, mode=0o700)

        yield self.downloadFileContentToWorker(self._getSshPrivateKeyPath(),
                                               private_key,
                                               workdir=workdir, mode=0o400)

        if self.sshHostKey is not None:
            known_hosts_contents = getSshKnownHostsContents(host_key)
            yield self.downloadFileContentToWorker(self._getSshHostKeyPath(),
                                                   known_hosts_contents,
                                                   workdir=workdir, mode=0o400)

        self.didDownloadSshPrivateKey = True
        defer.returnValue(RC_SUCCESS)
Exemplo n.º 3
0
    def verifyCode(self, code):
        # everything in deferToThread is not counted with trial  --coverage :-(
        def thd(client_id, client_secret):
            url = self.tokenUri
            data = {'redirect_uri': self.loginUri, 'code': code,
                    'grant_type': self.grantType}
            auth = None
            if self.getTokenUseAuthHeaders:
                auth = (client_id, client_secret)
            else:
                data.update(
                    {'client_id': client_id, 'client_secret': client_secret})
            data.update(self.tokenUriAdditionalParams)
            response = requests.post(
                url, data=data, auth=auth, verify=self.sslVerify)
            response.raise_for_status()
            responseContent = bytes2unicode(response.content)
            try:
                content = json.loads(responseContent)
            except ValueError:
                content = parse_qs(responseContent)
                for k, v in content.items():
                    content[k] = v[0]
            except TypeError:
                content = responseContent

            session = self.createSessionFromToken(content)
            return self.getUserInfoFromOAuthClient(session)
        p = Properties()
        p.master = self.master
        client_id = yield p.render(self.clientId)
        client_secret = yield p.render(self.clientSecret)
        result = yield threads.deferToThread(thd, client_id, client_secret)
        return result
Exemplo n.º 4
0
    def _downloadSshPrivateKeyIfNeeded(self):
        if self.sshPrivateKey is None:
            defer.returnValue(RC_SUCCESS)

        p = Properties()
        p.master = self.master
        private_key = yield p.render(self.sshPrivateKey)

        # not using self.workdir because it may be changed depending on step
        # options
        workdir = self._getSshDataWorkDir()

        rel_key_path = self.build.path_module.relpath(
            self._getSshPrivateKeyPath(), workdir)
        rel_wrapper_script_path = self.build.path_module.relpath(
            self._getSshWrapperScriptPath(), workdir)

        yield self.runMkdir(self._getSshDataPath())

        if not self.supportsSshPrivateKeyAsEnvOption:
            yield self.downloadFileContentToWorker(rel_wrapper_script_path,
                                                   self._getSshWrapperScript(),
                                                   workdir=workdir,
                                                   mode=0o700)

        yield self.downloadFileContentToWorker(rel_key_path,
                                               private_key,
                                               workdir=workdir,
                                               mode=0o400)

        self.didDownloadSshPrivateKey = True
        defer.returnValue(RC_SUCCESS)
Exemplo n.º 5
0
 def reconfigServiceWithSibling(self, sibling):
     # only reconfigure if sibling is configured differently.
     # sibling == self is using ComparableMixin's implementation
     # only compare compare_attrs
     if self.configured and sibling == self:
         defer.returnValue(None)
     self.configured = True
     # render renderables in parallel
     # Properties import to resolve cyclic import issue
     from buildbot.process.properties import Properties
     p = Properties()
     p.master = self.master
     # render renderables in parallel
     secrets = []
     kwargs = {}
     accumulateClassList(self.__class__, 'secrets', secrets)
     for k, v in sibling._config_kwargs.items():
         if k in secrets:
             value = yield p.render(v)
             setattr(self, k, value)
             kwargs.update({k: value})
         else:
             kwargs.update({k: v})
     d = yield self.reconfigService(*sibling._config_args,
                                    **sibling._config_kwargs)
     defer.returnValue(d)
Exemplo n.º 6
0
    def reconfigServiceWithSibling(self, sibling):
        # only reconfigure if sibling is configured differently.
        # sibling == self is using ComparableMixin's implementation
        # only compare compare_attrs
        if self.configured and sibling == self:
            return None
        self.configured = True
        # render renderables in parallel
        # Properties import to resolve cyclic import issue
        from buildbot.process.properties import Properties
        p = Properties()
        p.master = self.master
        # render renderables in parallel
        secrets = []
        kwargs = {}
        accumulateClassList(self.__class__, 'secrets', secrets)
        for k, v in sibling._config_kwargs.items():
            if k in secrets:
                # for non reconfigurable services, we force the attribute
                v = yield p.render(v)
                setattr(sibling, k, v)
                setattr(self, k, v)
            kwargs[k] = v

        d = yield self.reconfigService(*sibling._config_args,
                                       **kwargs)
        return d
Exemplo n.º 7
0
    def reconfigServiceWithSibling(self, sibling):
        # only reconfigure if sibling is configured differently.
        # sibling == self is using ComparableMixin's implementation
        # only compare compare_attrs
        if self.configured and sibling == self:
            defer.returnValue(None)
        self.configured = True
        # render renderables in parallel
        # Properties import to resolve cyclic import issue
        from buildbot.process.properties import Properties
        p = Properties()
        p.master = self.master
        # render renderables in parallel
        secrets = []
        kwargs = {}
        accumulateClassList(self.__class__, 'secrets', secrets)
        for k, v in sibling._config_kwargs.items():
            if k in secrets:
                # for non reconfigurable services, we force the attribute
                v = yield p.render(v)
                setattr(sibling, k, v)
                setattr(self, k, v)
            kwargs[k] = v

        d = yield self.reconfigService(*sibling._config_args, **kwargs)
        defer.returnValue(d)
Exemplo n.º 8
0
    def verifyCode(self, code):
        # everything in deferToThread is not counted with trial  --coverage :-(
        def thd(client_id, client_secret):
            url = self.tokenUri
            data = {'redirect_uri': self.loginUri, 'code': code,
                    'grant_type': self.grantType}
            auth = None
            if self.getTokenUseAuthHeaders:
                auth = (client_id, client_secret)
            else:
                data.update(
                    {'client_id': client_id, 'client_secret': client_secret})
            data.update(self.tokenUriAdditionalParams)
            response = requests.post(
                url, data=data, auth=auth, verify=self.sslVerify)
            response.raise_for_status()
            responseContent = bytes2unicode(response.content)
            try:
                content = json.loads(responseContent)
            except ValueError:
                content = parse_qs(responseContent)
                for k, v in content.items():
                    content[k] = v[0]
            except TypeError:
                content = responseContent

            session = self.createSessionFromToken(content)
            return self.getUserInfoFromOAuthClient(session)
        p = Properties()
        p.master = self.master
        client_id = yield p.render(self.clientId)
        client_secret = yield p.render(self.clientSecret)
        result = yield threads.deferToThread(thd, client_id, client_secret)
        return result
Exemplo n.º 9
0
    def _get_commit_msg(self, repo, sha):
        '''
        :param repo: the repo full name, ``{owner}/{project}``.
            e.g. ``buildbot/buildbot``
        '''

        headers = {
            'User-Agent': 'Buildbot',
        }
        if self._token:
            p = Properties()
            p.master = self.master
            token = yield p.render(self._token)
            headers['Authorization'] = 'token ' + token

        url = f'/repos/{repo}/commits/{sha}'
        http = yield httpclientservice.HTTPClientService.getService(
            self.master,
            self.github_api_endpoint,
            headers=headers,
            debug=self.debug,
            verify=self.verify)
        res = yield http.get(url)
        if 200 <= res.code < 300:
            data = yield res.json()
            return data['commit']['message']

        log.msg(f'Failed fetching PR commit message: response code {res.code}')
        return 'No message field'
Exemplo n.º 10
0
    def _downloadSshPrivateKeyIfNeeded(self):
        if self.sshPrivateKey is None:
            defer.returnValue(RC_SUCCESS)

        p = Properties()
        p.master = self.master
        private_key = yield p.render(self.sshPrivateKey)

        # not using self.workdir because it may be changed depending on step
        # options
        workdir = self._getSshDataWorkDir()

        rel_key_path = self.build.path_module.relpath(
                self._getSshPrivateKeyPath(), workdir)
        rel_wrapper_script_path = self.build.path_module.relpath(
                self._getSshWrapperScriptPath(), workdir)

        yield self.runMkdir(self._getSshDataPath())

        if not self.supportsSshPrivateKeyAsEnvOption:
            yield self.downloadFileContentToWorker(rel_wrapper_script_path,
                                                   self._getSshWrapperScript(),
                                                   workdir=workdir, mode=0o700)

        yield self.downloadFileContentToWorker(rel_key_path, private_key,
                                               workdir=workdir, mode=0o400)

        self.didDownloadSshPrivateKey = True
        defer.returnValue(RC_SUCCESS)
Exemplo n.º 11
0
    def renderSecrets(self, *args):
        # Properties import to resolve cyclic import issue
        from buildbot.process.properties import Properties
        p = Properties()
        p.master = self.master

        if len(args) == 1:
            return p.render(args[0])

        return defer.gatherResults([p.render(s) for s in args], consumeErrors=True)
Exemplo n.º 12
0
    def renderSecrets(self, *args):
        # Properties import to resolve cyclic import issue
        from buildbot.process.properties import Properties
        p = Properties()
        p.master = self.master

        if len(args) == 1:
            return p.render(args[0])

        return defer.gatherResults([p.render(s) for s in args], consumeErrors=True)
Exemplo n.º 13
0
    def getChanges(self, request):
        """
        Reponds only to POST events and starts the build process

        :arguments:
            request
                the http request object
        """
        expected_secret = isinstance(self.options,
                                     dict) and self.options.get('secret')
        if expected_secret:
            received_secret = request.getHeader(_HEADER_GITLAB_TOKEN)
            received_secret = bytes2unicode(received_secret)

            p = Properties()
            p.master = self.master
            expected_secret_value = yield p.render(expected_secret)

            if received_secret != expected_secret_value:
                raise ValueError("Invalid secret")
        try:
            content = request.content.read()
            payload = json.loads(bytes2unicode(content))
        except Exception as e:
            raise ValueError("Error loading JSON: " + str(e)) from e
        event_type = request.getHeader(_HEADER_EVENT)
        event_type = bytes2unicode(event_type)
        # newer version of gitlab have a object_kind parameter,
        # which allows not to use the http header
        event_type = payload.get('object_kind', event_type)
        codebase = request.args.get(b'codebase', [None])[0]
        codebase = bytes2unicode(codebase)
        if event_type in ("push", "tag_push", "Push Hook"):
            user = payload['user_name']
            repo = payload['repository']['name']
            repo_url = payload['repository']['url']
            changes = self._process_change(payload,
                                           user,
                                           repo,
                                           repo_url,
                                           event_type,
                                           codebase=codebase)
        elif event_type == 'merge_request':
            changes = self._process_merge_request_change(payload,
                                                         event_type,
                                                         codebase=codebase)
        else:
            changes = []
        if changes:
            log.msg(
                f"Received {len(changes)} changes from {event_type} gitlab event"
            )
        return (changes, 'git')
Exemplo n.º 14
0
    def _get_payload(self, request):
        content = request.content.read()
        content = bytes2unicode(content)

        signature = request.getHeader(_HEADER_SIGNATURE)
        signature = bytes2unicode(signature)

        if not signature and self._strict:
            raise ValueError('Request has no required signature')

        if self._secret and signature:
            try:
                hash_type, hexdigest = signature.split('=')
            except ValueError:
                raise ValueError(
                    'Wrong signature format: {}'.format(signature))

            if hash_type != 'sha1':
                raise ValueError('Unknown hash type: {}'.format(hash_type))

            p = Properties()
            p.master = self.master
            rendered_secret = yield p.render(self._secret)

            mac = hmac.new(unicode2bytes(rendered_secret),
                           msg=unicode2bytes(content),
                           digestmod=sha1)

            def _cmp(a, b):
                try:
                    # try the more secure compare_digest() first
                    from hmac import compare_digest
                    return compare_digest(a, b)
                except ImportError:  # pragma: no cover
                    # and fallback to the insecure simple comparison otherwise
                    return a == b

            if not _cmp(bytes2unicode(mac.hexdigest()), hexdigest):
                raise ValueError('Hash mismatch')

        content_type = request.getHeader(b'Content-Type')

        if content_type == b'application/json':
            payload = json.loads(content)
        elif content_type == b'application/x-www-form-urlencoded':
            payload = json.loads(bytes2unicode(request.args[b'payload'][0]))
        else:
            raise ValueError('Unknown content type: {}'.format(content_type))

        log.msg("Payload: {}".format(payload), logLevel=logging.DEBUG)

        return payload
Exemplo n.º 15
0
 def getLoginURL(self, redirect_url):
     """
     Returns the url to redirect the user to for user consent
     """
     p = Properties()
     p.master = self.master
     clientId = yield p.render(self.clientId)
     oauth_params = {'redirect_uri': self.loginUri,
                     'client_id': clientId, 'response_type': 'code'}
     if redirect_url is not None:
         oauth_params['state'] = urlencode(dict(redirect=redirect_url))
     oauth_params.update(self.authUriAdditionalParams)
     sorted_oauth_params = sorted(oauth_params.items(), key=lambda val: val[0])
     return "%s?%s" % (self.authUri, urlencode(sorted_oauth_params))
Exemplo n.º 16
0
 def getLoginURL(self, redirect_url):
     """
     Returns the url to redirect the user to for user consent
     """
     p = Properties()
     p.master = self.master
     clientId = yield p.render(self.clientId)
     oauth_params = {'redirect_uri': self.loginUri,
                     'client_id': clientId, 'response_type': 'code'}
     if redirect_url is not None:
         oauth_params['state'] = urlencode(dict(redirect=redirect_url))
     oauth_params.update(self.authUriAdditionalParams)
     sorted_oauth_params = sorted(oauth_params.items(), key=lambda val: val[0])
     return "%s?%s" % (self.authUri, urlencode(sorted_oauth_params))
Exemplo n.º 17
0
 def newChangeSource(self,
                     owner,
                     repo,
                     endpoint='https://api.github.com',
                     **kwargs):
     http_headers = {'User-Agent': 'Buildbot'}
     token = kwargs.get('token', None)
     if token:
         p = Properties()
         p.master = self.master
         token = yield p.render(token)
         http_headers.update({'Authorization': 'token ' + token})
     self._http = yield fakehttpclientservice.HTTPClientService.getService(
         self.master, self, endpoint, headers=http_headers)
     self.changesource = GitHubPullrequestPoller(owner, repo, **kwargs)
Exemplo n.º 18
0
    def _downloadSshPrivateKeyIfNeeded(self):
        if self.sshPrivateKey is None:
            return RC_SUCCESS

        p = Properties()
        p.master = self.master
        private_key = yield p.render(self.sshPrivateKey)
        host_key = yield p.render(self.sshHostKey)
        known_hosts_contents = yield p.render(self.sshKnownHosts)

        # not using self.workdir because it may be changed depending on step
        # options
        workdir = self._getSshDataWorkDir()

        ssh_data_path = self._getSshDataPath()
        yield self.runMkdir(ssh_data_path)

        private_key_path = self._getSshPrivateKeyPath(ssh_data_path)
        yield self.downloadFileContentToWorker(private_key_path,
                                               private_key,
                                               workdir=workdir,
                                               mode=0o400)

        known_hosts_path = None
        if self.sshHostKey is not None or self.sshKnownHosts is not None:
            known_hosts_path = self._getSshHostKeyPath(ssh_data_path)

            if self.sshHostKey is not None:
                known_hosts_contents = getSshKnownHostsContents(host_key)
            yield self.downloadFileContentToWorker(known_hosts_path,
                                                   known_hosts_contents,
                                                   workdir=workdir,
                                                   mode=0o400)

        if not self.supportsSshPrivateKeyAsEnvOption:
            script_path = self._getSshWrapperScriptPath(ssh_data_path)
            script_contents = getSshWrapperScriptContents(
                private_key_path, known_hosts_path)

            yield self.downloadFileContentToWorker(script_path,
                                                   script_contents,
                                                   workdir=workdir,
                                                   mode=0o700)

        self.didDownloadSshPrivateKey = True
        return RC_SUCCESS
Exemplo n.º 19
0
    def _get_payload(self, request):
        content = request.content.read()
        content = bytes2unicode(content)

        signature = request.getHeader(_HEADER_SIGNATURE)
        signature = bytes2unicode(signature)

        if not signature and self._strict:
            raise ValueError('Request has no required signature')

        if self._secret and signature:
            try:
                hash_type, hexdigest = signature.split('=')
            except ValueError as e:
                raise ValueError(f'Wrong signature format: {signature}') from e

            if hash_type != 'sha1':
                raise ValueError(f'Unknown hash type: {hash_type}')

            p = Properties()
            p.master = self.master
            rendered_secret = yield p.render(self._secret)

            mac = hmac.new(unicode2bytes(rendered_secret),
                           msg=unicode2bytes(content),
                           digestmod=sha1)

            def _cmp(a, b):
                return hmac.compare_digest(a, b)

            if not _cmp(bytes2unicode(mac.hexdigest()), hexdigest):
                raise ValueError('Hash mismatch')

        content_type = request.getHeader(b'Content-Type')

        if content_type == b'application/json':
            payload = json.loads(content)
        elif content_type == b'application/x-www-form-urlencoded':
            payload = json.loads(bytes2unicode(request.args[b'payload'][0]))
        else:
            raise ValueError(f'Unknown content type: {content_type}')

        log.msg(f"Payload: {payload}", logLevel=logging.DEBUG)

        return payload
Exemplo n.º 20
0
    async def _client(self):
        # return if the service has been already initialized
        if self._http:
            return self._http

        # render the secrets passed to tokens
        props = Properties()
        props.master = self.master
        tokens = [await props.render(token) for token in self._tokens]

        self._http = await GithubClientService.getService(
            self.master,
            self.github_api_endpoint,
            tokens=tokens,
            headers=self.headers,
            debug=self.debug,
            verify=self.verify)
        return self._http
Exemplo n.º 21
0
 def requestAvatarId(self, creds):
     p = Properties()
     p.master = self.master
     username = bytes2unicode(creds.username)
     try:
         yield self.master.initLock.acquire()
         if username in self.users:
             password, _ = self.users[username]
             password = yield p.render(password)
             matched = yield defer.maybeDeferred(creds.checkPassword,
                                                 unicode2bytes(password))
             if not matched:
                 log.msg("invalid login from user '{}'".format(username))
                 raise error.UnauthorizedLogin()
             defer.returnValue(creds.username)
         log.msg("invalid login from unknown user '{}'".format(username))
         raise error.UnauthorizedLogin()
     finally:
         eventually(self.master.initLock.release)
Exemplo n.º 22
0
 def requestAvatarId(self, creds):
     p = Properties()
     p.master = self.master
     username = bytes2unicode(creds.username)
     try:
         yield self.master.initLock.acquire()
         if username in self.users:
             password, _ = self.users[username]
             password = yield p.render(password)
             matched = yield defer.maybeDeferred(
                 creds.checkPassword, unicode2bytes(password))
             if not matched:
                 log.msg("invalid login from user '%s'" % creds.username)
                 raise error.UnauthorizedLogin()
             defer.returnValue(creds.username)
         log.msg("invalid login from unknown user '%s'" % creds.username)
         raise error.UnauthorizedLogin()
     finally:
         yield self.master.initLock.release()
Exemplo n.º 23
0
 def requestAvatarId(self, creds):
     p = Properties()
     p.master = self.master
     username = bytes2unicode(creds.username)
     try:
         yield self.master.initLock.acquire()
         if username in self.users:
             password, _ = self.users[username]
             password = yield p.render(password)
             matched = creds.checkPassword(unicode2bytes(password))
             if not matched:
                 log.msg("invalid login from user '{}'".format(username))
                 raise error.UnauthorizedLogin()
             return creds.username
         log.msg("invalid login from unknown user '{}'".format(username))
         raise error.UnauthorizedLogin()
     finally:
         # brake the callback stack by returning to the reactor
         # before waking up other waiters
         eventually(self.master.initLock.release)
Exemplo n.º 24
0
 def requestAvatarId(self, creds):
     p = Properties()
     p.master = self.master
     username = bytes2unicode(creds.username)
     try:
         yield self.master.initLock.acquire()
         if username in self.users:
             password, _ = self.users[username]
             password = yield p.render(password)
             matched = yield defer.maybeDeferred(
                 creds.checkPassword, unicode2bytes(password))
             if not matched:
                 log.msg("invalid login from user '{}'".format(username))
                 raise error.UnauthorizedLogin()
             return creds.username
         log.msg("invalid login from unknown user '{}'".format(username))
         raise error.UnauthorizedLogin()
     finally:
         # brake the callback stack by returning to the reactor
         # before waking up other waiters
         eventually(self.master.initLock.release)
Exemplo n.º 25
0
    def _downloadSshPrivateKeyIfNeeded(self):
        if self.sshPrivateKey is None:
            return RC_SUCCESS

        p = Properties()
        p.master = self.master
        private_key = yield p.render(self.sshPrivateKey)
        host_key = yield p.render(self.sshHostKey)

        # not using self.workdir because it may be changed depending on step
        # options
        workdir = self._getSshDataWorkDir()

        ssh_data_path = self._getSshDataPath()
        yield self.runMkdir(ssh_data_path)

        if not self.supportsSshPrivateKeyAsEnvOption:
            script_path = self._getSshWrapperScriptPath(ssh_data_path)
            script_contents = getSshWrapperScriptContents(
                self._getSshPrivateKeyPath(ssh_data_path))

            yield self.downloadFileContentToWorker(script_path,
                                                   script_contents,
                                                   workdir=workdir, mode=0o700)

        private_key_path = self._getSshPrivateKeyPath(ssh_data_path)
        yield self.downloadFileContentToWorker(private_key_path,
                                               private_key,
                                               workdir=workdir, mode=0o400)

        if self.sshHostKey is not None:
            known_hosts_path = self._getSshHostKeyPath(ssh_data_path)
            known_hosts_contents = getSshKnownHostsContents(host_key)
            yield self.downloadFileContentToWorker(known_hosts_path,
                                                   known_hosts_contents,
                                                   workdir=workdir, mode=0o400)

        self.didDownloadSshPrivateKey = True
        return RC_SUCCESS
Exemplo n.º 26
0
    def getChanges(self, request):
        secret = None
        if isinstance(self.options, dict):
            secret = self.options.get('secret')
        try:
            content = request.content.read()
            content_text = bytes2unicode(content)
            payload = json.loads(content_text)
        except Exception as exception:
            raise ValueError('Error loading JSON: ' + str(exception))

        if secret is not None:
            p = Properties()
            p.master = self.master
            rendered_secret = yield p.render(secret)
            signature = hmac.new(unicode2bytes(rendered_secret),
                                 unicode2bytes(content_text.strip()),
                                 digestmod=hashlib.sha256)
            header_signature = bytes2unicode(
                request.getHeader(_HEADER_SIGNATURE))
            if signature.hexdigest() != header_signature:
                raise ValueError('Invalid secret')

        event_type = bytes2unicode(request.getHeader(_HEADER_EVENT_TYPE))
        log.msg("Received event '{}' from gitea".format(event_type))

        codebases = request.args.get('codebase', [None])
        codebase = bytes2unicode(codebases[0])
        changes = []

        handler_function = getattr(self, 'process_{}'.format(event_type), None)
        if not handler_function:
            log.msg("Ignoring gitea event '{}'".format(event_type))
        else:
            changes = handler_function(payload, event_type, codebase)

        return (changes, 'git')
Exemplo n.º 27
0
    def command_FORCE(self, args):
        # FIXME: NEED TO THINK ABOUT!
        errReply = "try '%s'" % (self.command_FORCE.usage)
        args = self.splitArgs(args)
        if not args:
            raise UsageError(errReply)
        what = args.pop(0)
        if what != "build":
            raise UsageError(errReply)
        opts = ForceOptions()
        opts.parseOptions(args)

        builderName = opts['builder']
        builder = yield self.getBuilder(buildername=builderName)
        branch = opts['branch']
        revision = opts['revision']
        codebase = opts['codebase']
        project = opts['project']
        reason = opts['reason']
        props = opts['props']

        if builderName is None:
            raise UsageError("you must provide a Builder, " + errReply)

        # keep weird stuff out of the branch, revision, and properties args.
        branch_validate = self.master.config.validation['branch']
        revision_validate = self.master.config.validation['revision']
        pname_validate = self.master.config.validation['property_name']
        pval_validate = self.master.config.validation['property_value']
        if branch and not branch_validate.match(branch):
            log.msg("bad branch '%s'" % branch)
            self.send("sorry, bad branch '%s'" % branch)
            return
        if revision and not revision_validate.match(revision):
            log.msg("bad revision '%s'" % revision)
            self.send("sorry, bad revision '%s'" % revision)
            return

        properties = Properties()
        properties.master = self.master

        if props:
            # split props into name:value dict
            pdict = {}
            propertylist = props.split(",")
            for prop in propertylist:
                splitproperty = prop.split("=", 1)
                pdict[splitproperty[0]] = splitproperty[1]

            # set properties
            for prop in pdict:
                pname = prop
                pvalue = pdict[prop]
                if not pname_validate.match(pname) \
                        or not pval_validate.match(pvalue):
                    log.msg("bad property name='%s', value='%s'" %
                            (pname, pvalue))
                    self.send("sorry, bad property name='%s', value='%s'" %
                              (pname, pvalue))
                    return
                properties.setProperty(pname, pvalue, "Force Build chat")

        reason = "forced: by %s: %s" % (self.describeUser(), reason)
        try:
            yield self.master.data.updates.addBuildset(
                builderids=[builder['builderid']],
                # For now, we just use
                # this as the id.
                scheduler="status.words",
                sourcestamps=[{
                    'codebase': codebase,
                    'branch': branch,
                    'revision': revision,
                    'project': project,
                    'repository': "null"
                }],
                reason=reason,
                properties=properties.asDict(),
                waited_for=False)
        except AssertionError as e:
            self.send("I can't: " + str(e))
Exemplo n.º 28
0
    def command_FORCE(self, args):
        # FIXME: NEED TO THINK ABOUT!
        errReply = "try '%s'" % (self.command_FORCE.usage)
        args = self.splitArgs(args)
        if not args:
            raise UsageError(errReply)
        what = args.pop(0)
        if what != "build":
            raise UsageError(errReply)
        opts = ForceOptions()
        opts.parseOptions(args)

        builderName = opts['builder']
        builder = yield self.getBuilder(buildername=builderName)
        branch = opts['branch']
        revision = opts['revision']
        codebase = opts['codebase']
        project = opts['project']
        reason = opts['reason']
        props = opts['props']

        if builderName is None:
            raise UsageError("you must provide a Builder, " + errReply)

        # keep weird stuff out of the branch, revision, and properties args.
        branch_validate = self.master.config.validation['branch']
        revision_validate = self.master.config.validation['revision']
        pname_validate = self.master.config.validation['property_name']
        pval_validate = self.master.config.validation['property_value']
        if branch and not branch_validate.match(branch):
            log.msg("bad branch '%s'" % branch)
            self.send("sorry, bad branch '%s'" % branch)
            return
        if revision and not revision_validate.match(revision):
            log.msg("bad revision '%s'" % revision)
            self.send("sorry, bad revision '%s'" % revision)
            return

        properties = Properties()
        properties.master = self.master

        if props:
            # split props into name:value dict
            pdict = {}
            propertylist = props.split(",")
            for prop in propertylist:
                splitproperty = prop.split("=", 1)
                pdict[splitproperty[0]] = splitproperty[1]

            # set properties
            for prop in pdict:
                pname = prop
                pvalue = pdict[prop]
                if not pname_validate.match(pname) \
                        or not pval_validate.match(pvalue):
                    log.msg("bad property name='%s', value='%s'" %
                            (pname, pvalue))
                    self.send("sorry, bad property name='%s', value='%s'" %
                              (pname, pvalue))
                    return
                properties.setProperty(pname, pvalue, "Force Build chat")

        reason = "forced: by %s: %s" % (self.describeUser(), reason)
        try:
            yield self.master.data.updates.addBuildset(builderids=[builder['builderid']],
                                                       # For now, we just use
                                                       # this as the id.
                                                       scheduler="status.words",
                                                       sourcestamps=[{
                                                           'codebase': codebase, 'branch': branch,
                                                           'revision': revision, 'project': project,
                                                           'repository': "null"}],
                                                       reason=reason,
                                                       properties=properties.asDict(),
                                                       waited_for=False)
        except AssertionError as e:
            self.send("I can't: " + str(e))
Exemplo n.º 29
0
    def command_FORCE(self, args, **kwargs):
        """force a build"""

        # FIXME: NEED TO THINK ABOUT!
        errReply = f"Try '{self.bot.commandPrefix}{self.command_FORCE.usage}'"
        args = self.splitArgs(args)
        if not args:
            raise UsageError(errReply)
        what = args.pop(0)
        if what != "build":
            raise UsageError(errReply)
        opts = ForceOptions()
        opts.parseOptions(args)

        builderName = opts['builder']
        builder = yield self.bot.getBuilder(buildername=builderName)
        branch = opts['branch']
        revision = opts['revision']
        codebase = opts['codebase']
        project = opts['project']
        reason = opts['reason']
        props = opts['props']

        if builderName is None:
            raise UsageError("you must provide a Builder, " + errReply)

        # keep weird stuff out of the branch, revision, and properties args.
        branch_validate = self.master.config.validation['branch']
        revision_validate = self.master.config.validation['revision']
        pname_validate = self.master.config.validation['property_name']
        pval_validate = self.master.config.validation['property_value']
        if branch and not branch_validate.match(branch):
            self.bot.log(f"Force: bad branch '{branch}'")
            self.send(f"Sorry, bad branch '{branch}'")
            return
        if revision and not revision_validate.match(revision):
            self.bot.log(f"Force: bad revision '{revision}'")
            self.send(f"Sorry, bad revision '{revision}'")
            return

        properties = Properties()
        properties.master = self.master

        if props:
            # split props into name:value dict
            pdict = {}
            propertylist = props.split(",")
            for prop in propertylist:
                splitproperty = prop.split("=", 1)
                pdict[splitproperty[0]] = splitproperty[1]

            # set properties
            for pname, pvalue in pdict.items():
                if not pname_validate.match(pname) \
                        or not pval_validate.match(pvalue):
                    self.bot.log(
                        f"Force: bad property name='{pname}', value='{pvalue}'"
                    )
                    self.send(
                        f"Sorry, bad property name='{pname}', value='{pvalue}'"
                    )
                    return
                properties.setProperty(pname, pvalue, "Force Build Chat")

        properties.setProperty("reason", reason, "Force Build Chat")
        properties.setProperty("owner", self.describeUser(),
                               "Force Build Chat")

        reason = f"forced: by {self.describeUser()}: {reason}"
        try:
            yield self.master.data.updates.addBuildset(
                builderids=[builder['builderid']],
                # For now, we just use
                # this as the id.
                scheduler="status.words",
                sourcestamps=[{
                    'codebase': codebase,
                    'branch': branch,
                    'revision': revision,
                    'project': project,
                    'repository': ""
                }],
                reason=reason,
                properties=properties.asDict(),
                waited_for=False)
        except AssertionError as e:
            self.send("I can't: " + str(e))
        else:
            self.send("Force build successfully requested.")