def supplement(self, request):
        """ Provide additional information for grouping """
        if request.get('ignored'):
            # Only supplement once.
            return

        history = request.find('history')
        if history is not None:
            age = request_age(request).total_seconds()
            request.set('aged', str(age >= self.request_age_threshold))

        request_type = request.find('./action').get('type')
        target = request.find('./action/target')
        target_project = target.get('project')
        target_package = target.get('package')
        devel, _ = devel_project_fallback(self.api.apiurl, target_project,
                                          target_package)
        if not devel and request_type == 'submit':
            devel = request.find('./action/source').get('project')
        if devel:
            target.set('devel_project', devel)
            StrategySuper.supplement(request)

        ring = self.ring_get(target_package)
        if ring:
            target.set('ring', ring)

        request_id = int(request.get('id'))
        if request_id in self.requests_ignored:
            request.set('ignored', str(self.requests_ignored[request_id]))
        else:
            request.set('ignored', 'False')

        request.set('postponed', 'False')
def notify(args):
    apiurl = osc.conf.config['apiurl']

    # devel_projects_get() only works for Factory as such
    # devel_project_fallback() must be used on a per package basis.
    packages = meta_get_packagelist(apiurl, args.project)
    maintainer_map = {}
    for package in packages:
        devel_project, devel_package = devel_project_fallback(apiurl, args.project, package)
        if devel_project and devel_package:
            devel_package_identifier = '/'.join([devel_project, devel_package])
            userids = maintainers_get(apiurl, devel_project, devel_package)
            for userid in userids:
                maintainer_map.setdefault(userid, set())
                maintainer_map[userid].add(devel_package_identifier)

    Config(args.project) # Ensure mail-* options are loaded for mail_send().
    subject = 'Packages you maintain are present in {}'.format(args.project)
    for userid, package_identifiers in maintainer_map.items():
        email = entity_email(apiurl, userid)
        message = 'The following packages you maintain are in {}:\n\n- {}'.format(
            args.project, '\n- '.join(sorted(package_identifiers)))

        mail_send(args.project, email, subject, message, dry=args.dry)
        print('notified {} of {} packages'.format(userid, len(package_identifiers)))
Esempio n. 3
0
    def devel_project_review_add(self, request, project, package, message='adding devel project review'):
        devel_project, devel_package = devel_project_fallback(self.apiurl, project, package)
        if not devel_project:
            self.logger.warning('no devel project found for {}/{}'.format(project, package))
            return False

        self.add_review(request, by_project=devel_project, by_package=devel_package, msg=message)
        return True
    def devel_project_review_add(self, request, project, package, message='adding devel project review'):
        devel_project, devel_package = devel_project_fallback(self.apiurl, project, package)
        if not devel_project:
            self.logger.warning('no devel project found for {}/{}'.format(project, package))
            return False

        self.add_review(request, by_project=devel_project, by_package=devel_package, msg=message)
        return True
    def check_action_add_role(self, request, action):
        # Decline add_role request (assumed the bot acting on requests to Factory or similar).
        message = 'Roles to packages are granted in the devel project, not in %s.' % action.tgt_project

        if action.tgt_package is not None:
            project, package = devel_project_fallback(self.apiurl, action.tgt_project, action.tgt_package)
            message += ' Send this request to {}/{}.'.format(project, package)

        self.review_messages['declined'] = message
        return False
    def check_action_add_role(self, request, action):
        # Decline add_role request (assumed the bot acting on requests to Factory or similar).
        message = 'Roles to packages are granted in the devel project, not in %s.' % action.tgt_project

        if action.tgt_package is not None:
            project, package = devel_project_fallback(self.apiurl, action.tgt_project, action.tgt_package)
            message += ' Send this request to {}/{}.'.format(project, package)

        self.review_messages['declined'] = message
        return False
def notify(args):
    import smtplib
    apiurl = osc.conf.config['apiurl']

    # devel_projects_get() only works for Factory as such
    # devel_project_fallback() must be used on a per package basis.
    packages = args.packages
    if not packages:
        packages = package_list_kind_filtered(apiurl, args.project)
    maintainer_map = {}
    for package in packages:
        devel_project, devel_package = devel_project_fallback(
            apiurl, args.project, package)
        if devel_project and devel_package:
            devel_package_identifier = '/'.join([devel_project, devel_package])
            userids = maintainers_get(apiurl, devel_project, devel_package)
            for userid in userids:
                maintainer_map.setdefault(userid, set())
                maintainer_map[userid].add(devel_package_identifier)

    subject = 'Packages you maintain are present in {}'.format(args.project)
    for userid, package_identifiers in maintainer_map.items():
        email = entity_email(apiurl, userid)
        message = """This is a friendly reminder about your packages in {}.

Please verify that the included packages are working as intended and
have versions appropriate for a stable release. Changes may be submitted until
April 26th [at the latest].

Keep in mind that some packages may be shared with SUSE Linux
Enterprise. Concerns with those should be raised via Bugzilla.

Please contact [email protected] if your package
needs special attention by the release team.

According to the information in OBS ("osc maintainer") you are
in charge of the following packages:

- {}""".format(args.project, '\n- '.join(sorted(package_identifiers)))

        log = 'notified {} of {} packages'.format(userid,
                                                  len(package_identifiers))
        try:
            mail_send(apiurl,
                      args.project,
                      email,
                      subject,
                      message,
                      dry=args.dry)
            print(log)
        except smtplib.SMTPRecipientsRefused:
            print('[FAILED ADDRESS] {} ({})'.format(log, email))
        except smtplib.SMTPException as e:
            print('[FAILED SMTP] {} ({})'.format(log, e))
Esempio n. 8
0
def notify(args):
    import smtplib
    apiurl = osc.conf.config['apiurl']

    # devel_projects_get() only works for Factory as such
    # devel_project_fallback() must be used on a per package basis.
    packages = args.packages
    if not packages:
        packages = package_list_without_links(apiurl, args.project)
    maintainer_map = {}
    for package in packages:
        devel_project, devel_package = devel_project_fallback(apiurl, args.project, package)
        if devel_project and devel_package:
            devel_package_identifier = '/'.join([devel_project, devel_package])
            userids = maintainers_get(apiurl, devel_project, devel_package)
            for userid in userids:
                maintainer_map.setdefault(userid, set())
                maintainer_map[userid].add(devel_package_identifier)

    subject = 'Packages you maintain are present in {}'.format(args.project)
    for userid, package_identifiers in maintainer_map.items():
        email = entity_email(apiurl, userid)
        message = """This is a friendly reminder about your packages in {}.

Please verify that the included packages are working as intended and
have versions appropriate for a stable release. Changes may be submitted until
April 26th [at the latest].

Keep in mind that some packages may be shared with SUSE Linux
Enterprise. Concerns with those should be raised via Bugzilla.

Please contact [email protected] if your package
needs special attention by the release team.

According to the information in OBS ("osc maintainer") you are
in charge of the following packages:

- {}""".format(
            args.project, '\n- '.join(sorted(package_identifiers)))

        log = 'notified {} of {} packages'.format(userid, len(package_identifiers))
        try:
            mail_send(apiurl, args.project, email, subject, message, dry=args.dry)
            print(log)
        except smtplib.SMTPRecipientsRefused as e:
            print('[FAILED ADDRESS] {} ({})'.format(log, email))
        except smtplib.SMTPException as e:
            print('[FAILED SMTP] {} ({})'.format(log, e))
Esempio n. 9
0
    def devel_project_review_add(self, request, project, package, message='adding devel project review'):
        devel_project, devel_package = devel_project_fallback(self.apiurl, project, package)
        if not devel_project:
            self.logger.warning('no devel project found for {}/{}'.format(project, package))
            return False

        try:
            self.add_review(request, by_project=devel_project, by_package=devel_package, msg=message)
        except HTTPError as e:
            # could happen when the bot is not actually a reviewer and has no permissions
            if e.code != 403:
                raise e
            self.logger.error('failed to add devel project review for {}/{}'.format(devel_project, devel_package))
            return False

        return True
Esempio n. 10
0
    def package_comments(self, project, repository):
        self.logger.info('{} package comments'.format(len(
            self.package_results)))

        for package, sections in self.package_results.items():
            if str2bool(
                    Config.get(self.apiurl, project).get(
                        'repo_checker-package-comment-devel', 'False')):
                bot_name_suffix = project
                comment_project, comment_package = devel_project_fallback(
                    self.apiurl, project, package)
                if comment_project is None or comment_package is None:
                    self.logger.warning(
                        'unable to find devel project for {}'.format(package))
                    continue

                message = 'The version of this package in [`{project}`](/package/show/{project}/{package}) ' \
                    'has installation issues and may not be installable:'.format(
                        project=project, package=package)
            else:
                bot_name_suffix = repository
                comment_project = project
                comment_package = package
                message = 'This package has installation issues and may not be installable from the `{}` ' \
                    'repository:'.format(repository)

            # Sort sections by text to group binaries together.
            sections = sorted(sections, key=lambda s: s.text)
            message += '\n\n<pre>\n{}\n</pre>'.format('\n'.join(
                [section.text for section in sections]).strip())

            # Generate a hash based on the binaries involved and the number of
            # sections. This eliminates version or release changes from causing
            # an update to the comment while still updating on relevant changes.
            binaries = set()
            for section in sections:
                binaries.update(section.binaries)
            info = ';'.join(['::'.join(sorted(binaries)), str(len(sections))])
            reference = hashlib.sha1(info).hexdigest()[:7]

            # Post comment on package in order to notifiy maintainers.
            self.comment_write(state='seen',
                               result=reference,
                               bot_name_suffix=bot_name_suffix,
                               project=comment_project,
                               package=comment_package,
                               message=message)
    def supplement(self, request):
        """ Provide additional information for grouping """
        if request.get('ignored'):
            # Only supplement once.
            return

        history = request.find('history')
        if history is not None:
            created = dateutil.parser.parse(
                request.find('history').get('when'))
            delta = datetime.utcnow() - created
            request.set(
                'aged',
                str(delta.total_seconds() >= self.request_age_threshold))

        request_type = request.find('./action').get('type')
        target = request.find('./action/target')
        target_project = target.get('project')
        target_package = target.get('package')
        devel, _ = devel_project_fallback(self.api.apiurl, target_project,
                                          target_package)
        if not devel and request_type == 'submit':
            devel = request.find('./action/source').get('project')
        if devel:
            target.set('devel_project', devel)
            StrategySuper.supplement(request)

        ring = self.ring_get(target_package)
        if ring:
            target.set('ring', ring)
        elif request_type == 'delete':
            # Delete requests should always be considered in a ring.
            target.set('ring', 'delete')

        request_id = int(request.get('id'))
        if request_id in self.requests_ignored:
            request.set('ignored', str(self.requests_ignored[request_id]))
        else:
            request.set('ignored', 'False')

        request.set('postponed', 'False')
    def supplement(self, request):
        """ Provide additional information for grouping """
        if request.get('ignored'):
            # Only supplement once.
            return

        history = request.find('history')
        if history is not None:
            age = request_age(request).total_seconds()
            request.set('aged', str(age >= self.request_age_threshold))

        request_type = request.find('./action').get('type')
        target = request.find('./action/target')
        target_project = target.get('project')
        target_package = target.get('package')
        devel, _ = devel_project_fallback(self.api.apiurl, target_project, target_package)
        if not devel and request_type == 'submit':
            devel = request.find('./action/source').get('project')
        if devel:
            target.set('devel_project', devel)
            StrategySuper.supplement(request)

        if target_project == self.api.cnonfree:
            target.set('nonfree', 'nonfree')

        ring = self.ring_get(target_package)
        if ring:
            target.set('ring', ring)
        elif not self.api.conlyadi and request_type == 'delete':
            # Delete requests should always be considered in a ring.
            target.set('ring', 'delete')

        request_id = int(request.get('id'))
        if request_id in self.requests_ignored:
            request.set('ignored', str(self.requests_ignored[request_id]))
        else:
            request.set('ignored', 'False')

        request.set('postponed', 'False')
Esempio n. 13
0
    def package_comments(self, project, repository):
        self.logger.info('{} package comments'.format(len(self.package_results)))

        for package, sections in self.package_results.items():
            if str2bool(Config.get(self.apiurl, project).get('repo_checker-package-comment-devel', 'False')):
                bot_name_suffix = project
                comment_project, comment_package = devel_project_fallback(self.apiurl, project, package)
                if comment_project is None or comment_package is None:
                    self.logger.warning('unable to find devel project for {}'.format(package))
                    continue

                message = 'The version of this package in [`{project}`](/package/show/{project}/{package}) ' \
                    'has installation issues and may not be installable:'.format(
                        project=project, package=package)
            else:
                bot_name_suffix = repository
                comment_project = project
                comment_package = package
                message = 'This package has installation issues and may not be installable from the `{}` ' \
                    'repository:'.format(repository)

            # Sort sections by text to group binaries together.
            sections = sorted(sections, key=lambda s: s.text)
            message += '\n\n<pre>\n{}\n</pre>'.format(
                '\n'.join([section.text for section in sections]).strip())

            # Generate a hash based on the binaries involved and the number of
            # sections. This eliminates version or release changes from causing
            # an update to the comment while still updating on relevant changes.
            binaries = set()
            for section in sections:
                binaries.update(section.binaries)
            info = ';'.join(['::'.join(sorted(binaries)), str(len(sections))])
            reference = hashlib.sha1(info).hexdigest()[:7]

            # Post comment on package in order to notifiy maintainers.
            self.comment_write(state='seen', result=reference, bot_name_suffix=bot_name_suffix,
                               project=comment_project, package=comment_package, message=message)