コード例 #1
0
def main():
    config = ConfigParser.ConfigParser()
    config.read(os.environ['REDMINE_BUGZILLA_CONF'])

    username = config.get('bugzilla', 'username')
    password = config.get('bugzilla', 'password')
    key = config.get('redmine', 'key')

    redmine = get_redmine_connection(key)
    BZ = get_bugzilla_connection(username, password)

    redmine_issues = [issue for issue in redmine.issue.filter(query_id=24)]

    non_closed_bug_with_ext_tracker = BUGZILLA_URL + '/buglist.cgi?bug_status=NEW&' \
        'bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&' \
        'bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&' \
        'columnlist=priority%2Cbug_severity%2Cbug_status%2Cshort_desc%2Cchangeddate%2C' \
        'component%2Ctarget_release%2Cassigned_to%2Creporter&f1=external_bugzilla.url&' \
        'list_id=3309842&o1=substring&query_format=advanced&v1=pulp.plan.io'
    bugzilla_bugs = BZ.query(RHBugzilla.url_to_query(non_closed_bug_with_ext_tracker))

    links_issues_record = ''
    ext_bug_record = ''

    for issue in redmine_issues:
        for custom_field in issue.custom_fields.resources:
            if custom_field['name'] == 'Bugzilla':
                if custom_field['value'] == '':
                    continue
                bug = BZ.getbug(int(custom_field['value']))
                links_back = False
                for external_bug in bug.external_bugs:
                    if external_bug['type']['description'] == 'Pulp Redmine' and \
                                    external_bug['ext_bz_bug_id'] == str(issue.id):
                        add_cc_list_to_bugzilla_bug(bug)
                        ext_params = {}
                        if external_bug['ext_description'] != issue.subject:
                            ext_params['ext_description'] = issue.subject
                        if external_bug['ext_status'] != issue.status.name:
                            ext_params['ext_status'] = issue.status.name
                        if external_bug['ext_priority'] != issue.priority.name:
                            ext_params['ext_priority'] = issue.priority.name
                        if len(ext_params.keys()) > 0:
                            ext_bug_record += 'Bugzilla bug %s updated from upstream bug %s with ' \
                                              '%s\n' % (bug.id, issue.id, ext_params)
                            ext_params['ids'] = external_bug['id']
                            BZ.update_external_tracker(**ext_params)
                            if 'ext_status' in ext_params:
                                bug.addcomment(
                                    'The Pulp upstream bug status is at %s. Updating the external '
                                    'tracker on this bug.' % issue.status.name)
                            if 'ext_priority' in ext_params:
                                bug.addcomment(
                                    'The Pulp upstream bug priority is at %s. Updating the '
                                    'external tracker on this bug.' % issue.priority.name)

                        # Remove the bug list gotten via search so we don't examine it again when
                        #  bugzilla_bugs are iterated through
                        bug_in_search_index_to_remove = None
                        for i, bug_in_search in enumerate(bugzilla_bugs):
                            if bug_in_search.id == bug.id:
                                bug_in_search_index_to_remove = i
                                break
                        if bug_in_search_index_to_remove is not None:
                            bugzilla_bugs.pop(bug_in_search_index_to_remove)

                        links_back = True
                if not links_back:
                    links_issues_record += 'Redmine #%s -> Bugzilla %s, but Bugzilla %s does not ' \
                                           'link back\n' % (issue.id, bug.id, bug.id)

    for bug in bugzilla_bugs:
        for external_bug in bug.external_bugs:
                if external_bug['type']['description'] == 'Pulp Redmine':
                    add_cc_list_to_bugzilla_bug(bug)
                    issue_id = external_bug['ext_bz_bug_id']
                    issue = redmine.issue.get(issue_id)
                    links_back = False
                    for custom_field in issue.custom_fields.resources:
                        if custom_field['name'] == 'Bugzilla':
                            try:
                                if int(custom_field['value']) == bug.id:
                                    links_back = True
                            except KeyError:
                                # If value isn't present this field is not linking back so continue
                                continue
                            except ValueError:
                                # If value is present but empty this field is not linking back
                                continue
                    if not links_back:
                        links_issues_record += 'Bugzilla #%s -> Redmine %s, but Redmine %s does ' \
                                               'not link back\n' % (bug.id, issue.id, issue.id)

    if ext_bug_record != '':
        print '\nBugzilla Updates From Upstream'
        print '------------------------------'
        print ext_bug_record

    if links_issues_record != '':
        print '\nLink Issues'
        print '-----------'
        print links_issues_record
        # Raise an exception so the job fails and Jenkins will send e-mail
        raise RuntimeError('Upstream/Downstream Link issues are detected')
コード例 #2
0
def main():
    config = ConfigParser.ConfigParser()
    config.read(os.environ['REDMINE_BUGZILLA_CONF'])

    username = config.get('bugzilla', 'username')
    password = config.get('bugzilla', 'password')
    key = config.get('redmine', 'key')

    redmine = get_redmine_connection(key)
    BZ = get_bugzilla_connection(username, password)

    bug_with_ext_tracker = \
        BUGZILLA_URL + '/buglist.cgi?classification=Red%20Hat&columnlist=priority%2Cbug_severity' \
                       '%2Cbug_status%2Cshort_desc%2Cchangeddate%2Ccomponent%2Ctarget_release%2C' \
                       'assigned_to%2Creporter&f1=external_bugzilla.url&list_id=7254713&o1=' \
                       'substring&product=Red%20Hat%20Satellite%206&query_format=advanced&' \
                       'resolution=---&resolution=CURRENTRELEASE&resolution=RAWHIDE&resolution=' \
                       'ERRATA&resolution=NEXTRELEASE&resolution=INSUFFICIENT_DATA&resolution=EOL' \
                       '&v1=pulp.plan.io'
    bugzilla_bugs = BZ.query(RHBugzilla.url_to_query(bug_with_ext_tracker))

    upstream_issues_checked_memo = {}  # A memo allowing us to never check an issue twice

    all_BZs = set()
    BZs_fixed_by_version = defaultdict(lambda : set())

    for i, bug in enumerate(bugzilla_bugs):
        # if i == 20:
        #     break
        all_BZs.add(bug.id)
        bug = BZ.getbug(bug.id)
        upstream_associated_issue_numbers = []
        for external_bug in bug.external_bugs:
            if external_bug['type']['description'] == 'Pulp Redmine':
                upstream_associated_issue_numbers.append(int(external_bug['ext_bz_bug_id']))

        upstream_fixed_versions_for_bz = []
        for upstream_id in upstream_associated_issue_numbers:

            # Check the memo to see if we already know the fix version
            if upstream_id in upstream_fixed_versions_for_bz:
                if upstream_fixed_versions_for_bz[upstream_id] != u'':
                    # We already know the upstream version with the fix available
                    upstream_fixed_versions_for_bz.append(
                        upstream_fixed_versions_for_bz[upstream_id]
                    )
                    all_BZs.add(bug.id)
                # The memo info was used so we can move on to the next upstream issue to check
                continue

            upstream_issue = redmine.issue.get(upstream_id)

            # Issues in 'External' are not actual issues so they should be ignored
            if upstream_issue.project.name == u'External':
                # Never check an upstream issue twice
                upstream_issues_checked_memo[upstream_id] = u''
                continue

            platform_release_field = upstream_issue.custom_fields.get(4)  # 'Platform Release' field

            # Never check an upstream issue twice
            upstream_issues_checked_memo[upstream_id] = platform_release_field[u'value']

            if platform_release_field[u'value'] != u'':
                upstream_fixed_versions_for_bz.append(platform_release_field[u'value'])
                all_BZs.add(bug.id)

        if upstream_fixed_versions_for_bz != []:
            fix_in = max([semantic_version.Version(v) for v in upstream_fixed_versions_for_bz])
            BZs_fixed_by_version[str(fix_in)].add(bug.id)

    upstream_versions = [semantic_version.Version(v) for v in BZs_fixed_by_version.keys()]
    upstream_versions.sort()  # Ensure in increasing order
    BZs_fixed_list = [BZs_fixed_by_version[str(v)] for v in upstream_versions]

    for i in range(1, len(BZs_fixed_list)):
        BZs_fixed_list[i] = BZs_fixed_list[i - 1] | BZs_fixed_list[i]

    for i, version in enumerate(upstream_versions):
        BZs_fixed_by_version[str(version)] = BZs_fixed_list[i]

    BZs_missing_by_version = {}
    for version, bugs in BZs_fixed_by_version.iteritems():
        BZs_missing_by_version[version] = all_BZs - BZs_fixed_by_version[version]

    minimum_version = semantic_version.Version(MINIMUM_VERSION)
    for v in upstream_versions:
        if v < minimum_version:
            continue
        bugs_in_this_version = BZs_missing_by_version[str(v)]
        print '%s, %s, https://bugzilla.redhat.com/buglist.cgi?quicksearch=%s' % (
            v, len(bugs_in_this_version), ','.join([str(i) for i in bugs_in_this_version])
        )
コード例 #3
0
def main():
    config = ConfigParser.ConfigParser()
    config.read(os.environ["REDMINE_BUGZILLA_CONF"])

    username = config.get("bugzilla", "username")
    password = config.get("bugzilla", "password")
    key = config.get("redmine", "key")

    redmine = get_redmine_connection(key)
    BZ = get_bugzilla_connection(username, password)

    redmine_issues = [issue for issue in redmine.issue.filter(query_id=24)]

    non_closed_bug_with_ext_tracker = (
        BUGZILLA_URL + "/buglist.cgi?bug_status=NEW&"
        "bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&"
        "bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&"
        "columnlist=priority%2Cbug_severity%2Cbug_status%2Cshort_desc%2Cchangeddate%2C"
        "component%2Ctarget_release%2Cassigned_to%2Creporter&f1=external_bugzilla.url&"
        "list_id=3309842&o1=substring&query_format=advanced&v1=pulp.plan.io"
    )
    bugzilla_bugs = BZ.query(RHBugzilla.url_to_query(non_closed_bug_with_ext_tracker))

    links_issues_record = ""
    ext_bug_record = ""
    downstream_state_issue_record = ""
    downstream_changes = ""

    for issue in redmine_issues:
        for custom_field in issue.custom_fields.resources:
            if custom_field["name"] == "Bugzillas":
                if custom_field["value"] == "":
                    continue
                for bug_id in [int(id_str) for id_str in custom_field["value"].split(",")]:
                    links_back = False
                    try:
                        bug = BZ.getbug(bug_id)
                    except xmlrpclib.Fault as e:
                        if e.faultCode == 102:
                            print "Bugzilla %s could not be accessed." % bug_id
                            continue
                        else:
                            raise
                    for external_bug in bug.external_bugs:
                        if external_bug["type"]["description"] == "Pulp Redmine" and external_bug[
                            "ext_bz_bug_id"
                        ] == str(issue.id):
                            add_cc_list_to_bugzilla_bug(bug)
                            ext_params = {}
                            if external_bug["ext_description"] != issue.subject:
                                ext_params["ext_description"] = issue.subject
                            if external_bug["ext_status"] != issue.status.name:
                                ext_params["ext_status"] = issue.status.name
                            if external_bug["ext_priority"] != issue.priority.name:
                                ext_params["ext_priority"] = issue.priority.name
                            if len(ext_params.keys()) > 0:
                                ext_bug_record += "Bugzilla bug %s updated from upstream bug %s " "with %s\n" % (
                                    bug.id,
                                    issue.id,
                                    ext_params,
                                )
                                ext_params["ids"] = external_bug["id"]
                                BZ.update_external_tracker(**ext_params)
                                if "ext_status" in ext_params:
                                    bug.addcomment(
                                        "The Pulp upstream bug status is at %s. Updating the "
                                        "external tracker on this bug." % issue.status.name
                                    )
                                if "ext_priority" in ext_params:
                                    bug.addcomment(
                                        "The Pulp upstream bug priority is at %s. Updating the "
                                        "external tracker on this bug." % issue.priority.name
                                    )
                            downstream_POST_plus = [
                                "POST",
                                "MODIFIED",
                                "ON_QA",
                                "VERIFIED",
                                "RELEASE_PENDING",
                                "CLOSED",
                            ]
                            upstream_POST_minus = ["NEW", "ASSIGNED", "POST"]
                            if bug.status in downstream_POST_plus and issue.status.name in upstream_POST_minus:
                                msg = "The downstream bug %s is at POST+ but the upstream bug %s " "at POST-.\n" % (
                                    bug.id,
                                    issue.id,
                                )
                                downstream_state_issue_record += msg
                            links_back = True
                    transition_to_post = []
                    for external_bug in bug.external_bugs:
                        if external_bug["type"]["description"] == "Foreman Issue Tracker":
                            # If the bug has an external foreman issue, don't transition the BZ
                            transition_to_post.append(False)
                        if external_bug["type"]["description"] == "Pulp Redmine":
                            if bug.status in ["NEW", "ASSIGNED"]:
                                if external_bug["ext_status"] in [
                                    "MODIFIED",
                                    "ON_QA",
                                    "VERIFIED",
                                    "CLOSED - CURRENTRELEASE",
                                ]:
                                    transition_to_post.append(True)
                                else:
                                    transition_to_post.append(False)
                    if not links_back:
                        links_issues_record += "Redmine #%s -> Bugzilla %s, but Bugzilla %s does " "not link back\n" % (
                            issue.id,
                            bug.id,
                            bug.id,
                        )
                    if len(transition_to_post) > 0 and all(transition_to_post):
                        msg = "All upstream Pulp bugs are at MODIFIED+. Moving this bug to POST."
                        bug.setstatus("POST", msg)
                        downstream_changes += "Bugzilla %s was transitioned to POST\n" % bug.id

    for bug in bugzilla_bugs:
        for external_bug in bug.external_bugs:
            if external_bug["type"]["description"] == "Pulp Redmine":
                add_cc_list_to_bugzilla_bug(bug)
                issue_id = external_bug["ext_bz_bug_id"]
                issue = redmine.issue.get(issue_id)
                links_back = False
                for custom_field in issue.custom_fields.resources:
                    if custom_field["name"] == "Bugzillas" and custom_field["value"]:
                        bug_list = [int(id_str) for id_str in custom_field["value"].split(",")]
                        for bug_id in bug_list:
                            try:
                                if bug_id == bug.id:
                                    links_back = True
                            except KeyError:
                                # If value isn't present this field is not linking back
                                continue
                            except ValueError:
                                # If value is present but empty this field is not linking back
                                continue
                if not links_back:
                    links_issues_record += "Bugzilla #%s -> Redmine %s, but Redmine %s does " "not link back\n" % (
                        bug.id,
                        issue.id,
                        issue.id,
                    )

    if ext_bug_record != "":
        print "\nBugzilla Updates From Upstream"
        print "------------------------------"
        print ext_bug_record

    if downstream_changes != "":
        print "\nBugzilla Transitions to POST"
        print "----------------------------"
        print downstream_changes

    if links_issues_record != "":
        print "\nLink Issues"
        print "-----------"
        print links_issues_record

    if downstream_state_issue_record != "":
        print "\nDownstream State Issues"
        print "-----------------------"
        print downstream_state_issue_record

    if links_issues_record != "" or downstream_state_issue_record != "":
        # Raise an exception so the job fails and Jenkins will send e-mail
        raise RuntimeError("We need a human here")
コード例 #4
0
def main():
    config = ConfigParser.ConfigParser()
    config.read(os.environ['REDMINE_BUGZILLA_CONF'])

    username = config.get('bugzilla', 'username')
    password = config.get('bugzilla', 'password')
    key = config.get('redmine', 'key')

    redmine = get_redmine_connection(key)
    BZ = get_bugzilla_connection(username, password)

    redmine_issues = [issue for issue in redmine.issue.filter(query_id=24)]

    non_closed_bug_with_ext_tracker = BUGZILLA_URL + '/buglist.cgi?bug_status=NEW&' \
        'bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&' \
        'bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&' \
        'columnlist=priority%2Cbug_severity%2Cbug_status%2Cshort_desc%2Cchangeddate%2C' \
        'component%2Ctarget_release%2Cassigned_to%2Creporter&f1=external_bugzilla.url&' \
        'list_id=3309842&o1=substring&query_format=advanced&v1=pulp.plan.io'
    bugzilla_bugs = BZ.query(
        RHBugzilla.url_to_query(non_closed_bug_with_ext_tracker))

    links_issues_record = ''
    ext_bug_record = ''
    downstream_state_issue_record = ''
    downstream_changes = ''
    new_failed_qa_record = ''
    failed_qa_bugzillas = []

    for issue in redmine_issues:
        for custom_field in issue.custom_fields.resources:
            if custom_field['name'] == 'Bugzillas':
                if custom_field['value'] == '':
                    continue
                for bug_id in [
                        int(id_str)
                        for id_str in custom_field['value'].split(',')
                ]:
                    links_back = False
                    if bug_id in failed_qa_bugzillas:
                        continue
                    try:
                        bug = BZ.getbug(bug_id)
                    except xmlrpclib.Fault as e:
                        if e.faultCode == 102:
                            print 'Bugzilla %s could not be accessed.' % bug_id
                            continue
                        else:
                            raise
                    for external_bug in bug.external_bugs:
                        if external_bug['type']['description'] == 'Pulp Redmine' and \
                                        external_bug['ext_bz_bug_id'] == str(issue.id):
                            add_cc_list_to_bugzilla_bug(bug)
                            ext_params = {}
                            if external_bug['ext_description'] != issue.subject:
                                ext_params['ext_description'] = issue.subject
                            if external_bug['ext_status'] != issue.status.name:
                                ext_params['ext_status'] = issue.status.name
                            if external_bug[
                                    'ext_priority'] != issue.priority.name:
                                ext_params[
                                    'ext_priority'] = issue.priority.name
                            if len(ext_params.keys()) > 0:
                                ext_bug_record += 'Bugzilla bug %s updated from upstream bug %s ' \
                                                  'with %s\n' % (bug.id, issue.id, ext_params)
                                ext_params['ids'] = external_bug['id']
                                BZ.update_external_tracker(**ext_params)
                                if 'ext_status' in ext_params:
                                    bug.addcomment(
                                        'The Pulp upstream bug status is at %s. Updating the '
                                        'external tracker on this bug.' %
                                        issue.status.name)
                                if 'ext_priority' in ext_params:
                                    bug.addcomment(
                                        'The Pulp upstream bug priority is at %s. Updating the '
                                        'external tracker on this bug.' %
                                        issue.priority.name)
                            downstream_POST_plus = [
                                'POST', 'MODIFIED', 'ON_QA', 'VERIFIED',
                                'RELEASE_PENDING', 'CLOSED'
                            ]
                            downstream_ACCEPTABLE_resolution = [
                                'NOTABUG', 'WONTFIX', 'DEFERRED', 'WORKSFORME'
                            ]
                            upstream_POST_minus = ['NEW', 'ASSIGNED', 'POST']
                            if bug.status in downstream_POST_plus and \
                                            issue.status.name in upstream_POST_minus:
                                if bug.resolution not in downstream_ACCEPTABLE_resolution:
                                    msg = 'The downstream bug %s is at POST+ but the upstream ' \
                                          'bug %s at POST-.\n' % (bug.id, issue.id)
                                    downstream_state_issue_record += msg
                            links_back = True
                    transition_to_post = []
                    for external_bug in bug.external_bugs:
                        if external_bug['type'][
                                'description'] == 'Foreman Issue Tracker':
                            # If the bug has an external foreman issue, don't transition the BZ
                            transition_to_post.append(False)
                        if external_bug['type'][
                                'description'] == 'Pulp Redmine':
                            if bug.status in ['NEW', 'ASSIGNED']:
                                if external_bug['ext_status'] in [
                                        'MODIFIED', 'ON_QA', 'VERIFIED',
                                        'CLOSED - CURRENTRELEASE'
                                ]:
                                    if 'FailedQA' in bug.cf_verified:
                                        needinfo = True
                                        external_bug_id = external_bug[
                                            'ext_bz_bug_id']
                                        redmine_issue = redmine.issue.get(
                                            external_bug_id)
                                        redmine_user_id = redmine_issue.assigned_to.id
                                        needinfo_email = redmine.user.get(
                                            redmine_user_id).mail
                                        msg = "Bugzilla %s failed QA. Needinfo is set for %s." % \
                                              (bug.id, needinfo_email)
                                        for flag in bug.flags:
                                            if flag['name'] == 'needinfo' and \
                                                            flag['requestee'] == needinfo_email:
                                                needinfo = False
                                        if needinfo:
                                            BZ.update_flags(
                                                bug.id, [{
                                                    "name": "needinfo",
                                                    "status": "?",
                                                    "requestee":
                                                    needinfo_email,
                                                    "new": True
                                                }])
                                            bug.addcomment("Requesting needsinfo from upstream " \
                                                           "developer %s because the 'FailedQA' " \
                                                           "flag is set." % needinfo_email)
                                            new_failed_qa_record += "%s\n" % msg
                                        print msg
                                        failed_qa_bugzillas.append(bug.id)
                                    else:
                                        transition_to_post.append(True)
                                else:
                                    transition_to_post.append(False)
                    if not links_back:
                        links_issues_record += 'Redmine #%s -> Bugzilla %s, but Bugzilla %s does ' \
                                               'not link back\n' % (issue.id, bug.id, bug.id)
                    if len(transition_to_post) > 0 and all(transition_to_post):
                        msg = 'All upstream Pulp bugs are at MODIFIED+. Moving this bug to POST.'
                        bug.setstatus('POST', msg)
                        downstream_changes += 'Bugzilla %s was transitioned to POST\n' % bug.id

    for bug in bugzilla_bugs:
        for external_bug in bug.external_bugs:
            if external_bug['type']['description'] == 'Pulp Redmine':
                add_cc_list_to_bugzilla_bug(bug)
                issue_id = external_bug['ext_bz_bug_id']
                issue = redmine.issue.get(issue_id)
                links_back = False
                for custom_field in issue.custom_fields.resources:
                    if custom_field['name'] == 'Bugzillas' and custom_field[
                            'value']:
                        bug_list = [
                            int(id_str)
                            for id_str in custom_field['value'].split(',')
                        ]
                        for bug_id in bug_list:
                            try:
                                if bug_id == bug.id:
                                    links_back = True
                            except KeyError:
                                # If value isn't present this field is not linking back
                                continue
                            except ValueError:
                                # If value is present but empty this field is not linking back
                                continue
                if not links_back:
                    links_issues_record += 'Bugzilla #%s -> Redmine %s, but Redmine %s does ' \
                                           'not link back\n' % (bug.id, issue.id, issue.id)

    if ext_bug_record != '':
        print '\nBugzilla Updates From Upstream'
        print '------------------------------'
        print ext_bug_record

    if downstream_changes != '':
        print '\nBugzilla Transitions to POST'
        print '----------------------------'
        print downstream_changes

    if links_issues_record != '':
        print '\nLink Issues'
        print '-----------'
        print links_issues_record

    if downstream_state_issue_record != '':
        print '\nDownstream State Issues'
        print '-----------------------'
        print downstream_state_issue_record

    if new_failed_qa_record != '':
        print '\nNew Bugzillas That Failed QA'
        print '----------------------------'
        print new_failed_qa_record

    if links_issues_record != '' or downstream_state_issue_record != '' or new_failed_qa_record:
        # Raise an exception so the job fails and Jenkins will send e-mail
        raise RuntimeError('We need a human here')
コード例 #5
0
def main():
    config = ConfigParser.ConfigParser()
    config.read(os.environ['REDMINE_BUGZILLA_CONF'])

    username = config.get('bugzilla', 'username')
    password = config.get('bugzilla', 'password')
    key = config.get('redmine', 'key')

    redmine = get_redmine_connection(key)
    BZ = get_bugzilla_connection(username, password)

    redmine_issues = [issue for issue in redmine.issue.filter(query_id=24)]

    non_closed_bug_with_ext_tracker = BUGZILLA_URL + '/buglist.cgi?bug_status=NEW&' \
        'bug_status=ASSIGNED&bug_status=POST&bug_status=MODIFIED&bug_status=ON_DEV&' \
        'bug_status=ON_QA&bug_status=VERIFIED&bug_status=RELEASE_PENDING&' \
        'columnlist=priority%2Cbug_severity%2Cbug_status%2Cshort_desc%2Cchangeddate%2C' \
        'component%2Ctarget_release%2Cassigned_to%2Creporter&f1=external_bugzilla.url&' \
        'list_id=3309842&o1=substring&query_format=advanced&v1=pulp.plan.io'
    bugzilla_bugs = BZ.query(RHBugzilla.url_to_query(non_closed_bug_with_ext_tracker))

    links_issues_record = ''
    ext_bug_record = ''
    downstream_state_issue_record = ''
    downstream_changes = ''

    for issue in redmine_issues:
        for custom_field in issue.custom_fields.resources:
            if custom_field['name'] == 'Bugzillas':
                if custom_field['value'] == '':
                    continue
                for bug_id in [int(id_str) for id_str in custom_field['value'].split(',')]:
                    links_back = False
                    try:
                        bug = BZ.getbug(bug_id)
                    except xmlrpclib.Fault as e:
                        if e.faultCode == 102:
                            print 'Bugzilla %s could not be accessed.' % bug_id
                            continue
                        else:
                            raise
                    transition_to_post = []
                    for external_bug in bug.external_bugs:
                        if external_bug['type']['description'] == 'Foreman Issue Tracker':
                            # If the bug has an external foreman issue, don't transition the BZ
                            transition_to_post.append(False)
                        if external_bug['type']['description'] == 'Pulp Redmine' and \
                                        external_bug['ext_bz_bug_id'] == str(issue.id):
                            add_cc_list_to_bugzilla_bug(bug)
                            ext_params = {}
                            if external_bug['ext_description'] != issue.subject:
                                ext_params['ext_description'] = issue.subject
                            if external_bug['ext_status'] != issue.status.name:
                                ext_params['ext_status'] = issue.status.name
                            if external_bug['ext_priority'] != issue.priority.name:
                                ext_params['ext_priority'] = issue.priority.name
                            if len(ext_params.keys()) > 0:
                                ext_bug_record += 'Bugzilla bug %s updated from upstream bug %s ' \
                                                  'with %s\n' % (bug.id, issue.id, ext_params)
                                ext_params['ids'] = external_bug['id']
                                BZ.update_external_tracker(**ext_params)
                                if 'ext_status' in ext_params:
                                    bug.addcomment(
                                        'The Pulp upstream bug status is at %s. Updating the '
                                        'external tracker on this bug.' % issue.status.name)
                                if 'ext_priority' in ext_params:
                                    bug.addcomment(
                                        'The Pulp upstream bug priority is at %s. Updating the '
                                        'external tracker on this bug.' % issue.priority.name)
                            if bug.status in ['NEW', 'ASSIGNED']:
                                if issue.status.name in ['MODIFIED', 'ON_QA', 'VERIFIED',
                                                         'CLOSED - CURRENTRELEASE']:
                                    transition_to_post.append(True)
                                else:
                                    transition_to_post.append(False)
                            downstream_POST_plus = ['POST', 'MODIFIED', 'ON_QA', 'VERIFIED',
                                                    'RELEASE_PENDING', 'CLOSED']
                            upstream_POST_minus = ['NEW', 'ASSIGNED', 'POST']
                            if bug.status in downstream_POST_plus and \
                                            issue.status.name in upstream_POST_minus:
                                msg = 'The downstream bug %s is at POST+ but the upstream bug %s ' \
                                      'at POST-.\n' % (bug.id, issue.id)
                                downstream_state_issue_record += msg
                            links_back = True
                    if not links_back:
                        links_issues_record += 'Redmine #%s -> Bugzilla %s, but Bugzilla %s does ' \
                                               'not link back\n' % (issue.id, bug.id, bug.id)
                    if len(transition_to_post) > 0 and all(transition_to_post):
                        msg = 'All upstream Pulp bugs are at MODIFIED+. Moving this bug to POST.'
                        bug.setstatus('POST', msg)
                        downstream_changes += 'Bugzilla %s was transitioned to POST\n' % bug.id

    for bug in bugzilla_bugs:
        for external_bug in bug.external_bugs:
                if external_bug['type']['description'] == 'Pulp Redmine':
                    add_cc_list_to_bugzilla_bug(bug)
                    issue_id = external_bug['ext_bz_bug_id']
                    issue = redmine.issue.get(issue_id)
                    links_back = False
                    for custom_field in issue.custom_fields.resources:
                        if custom_field['name'] == 'Bugzillas' and custom_field['value']:
                            bug_list = [int(id_str) for id_str in custom_field['value'].split(',')]
                            for bug_id in bug_list:
                                try:
                                    if bug_id == bug.id:
                                        links_back = True
                                except KeyError:
                                    # If value isn't present this field is not linking back
                                    continue
                                except ValueError:
                                    # If value is present but empty this field is not linking back
                                    continue
                    if not links_back:
                        links_issues_record += 'Bugzilla #%s -> Redmine %s, but Redmine %s does ' \
                                               'not link back\n' % (bug.id, issue.id, issue.id)

    if ext_bug_record != '':
        print '\nBugzilla Updates From Upstream'
        print '------------------------------'
        print ext_bug_record

    if downstream_changes != '':
        print '\nBugzilla Transitions to POST'
        print '----------------------------'
        print downstream_changes

    if links_issues_record != '':
        print '\nLink Issues'
        print '-----------'
        print links_issues_record

    if downstream_state_issue_record != '':
        print '\nDownstream State Issues'
        print '-----------------------'
        print downstream_state_issue_record

    if links_issues_record != '' or downstream_state_issue_record != '':
        # Raise an exception so the job fails and Jenkins will send e-mail
        raise RuntimeError('We need a human here')
コード例 #6
0
def main():
    config = ConfigParser.ConfigParser()
    config.read(os.environ['REDMINE_BUGZILLA_CONF'])

    username = config.get('bugzilla', 'username')
    password = config.get('bugzilla', 'password')
    key = config.get('redmine', 'key')

    redmine = get_redmine_connection(key)
    BZ = get_bugzilla_connection(username, password)

    bug_with_ext_tracker = \
        BUGZILLA_URL + '/buglist.cgi?classification=Red%20Hat&columnlist=priority%2Cbug_severity' \
                       '%2Cbug_status%2Cshort_desc%2Cchangeddate%2Ccomponent%2Ctarget_release%2C' \
                       'assigned_to%2Creporter&f1=external_bugzilla.url&list_id=7254713&o1=' \
                       'substring&product=Red%20Hat%20Satellite%206&query_format=advanced&' \
                       'resolution=---&resolution=CURRENTRELEASE&resolution=RAWHIDE&resolution=' \
                       'ERRATA&resolution=NEXTRELEASE&resolution=INSUFFICIENT_DATA&resolution=EOL' \
                       '&v1=pulp.plan.io'
    bugzilla_bugs = BZ.query(RHBugzilla.url_to_query(bug_with_ext_tracker))

    upstream_issues_checked_memo = {
    }  # A memo allowing us to never check an issue twice

    all_BZs = set()
    BZs_fixed_by_version = defaultdict(lambda: set())

    for i, bug in enumerate(bugzilla_bugs):
        # if i == 20:
        #     break
        all_BZs.add(bug.id)
        bug = BZ.getbug(bug.id)
        upstream_associated_issue_numbers = []
        for external_bug in bug.external_bugs:
            if external_bug['type']['description'] == 'Pulp Redmine':
                upstream_associated_issue_numbers.append(
                    int(external_bug['ext_bz_bug_id']))

        upstream_fixed_versions_for_bz = []
        for upstream_id in upstream_associated_issue_numbers:

            # Check the memo to see if we already know the fix version
            if upstream_id in upstream_fixed_versions_for_bz:
                if upstream_fixed_versions_for_bz[upstream_id] != u'':
                    # We already know the upstream version with the fix available
                    upstream_fixed_versions_for_bz.append(
                        upstream_fixed_versions_for_bz[upstream_id])
                    all_BZs.add(bug.id)
                # The memo info was used so we can move on to the next upstream issue to check
                continue

            upstream_issue = redmine.issue.get(upstream_id)

            # Issues in 'External' are not actual issues so they should be ignored
            if upstream_issue.project.name == u'External':
                # Never check an upstream issue twice
                upstream_issues_checked_memo[upstream_id] = u''
                continue

            platform_release_field = upstream_issue.custom_fields.get(
                4)  # 'Platform Release' field

            # Never check an upstream issue twice
            upstream_issues_checked_memo[upstream_id] = platform_release_field[
                u'value']

            if platform_release_field[u'value'] != u'':
                upstream_fixed_versions_for_bz.append(
                    platform_release_field[u'value'])
                all_BZs.add(bug.id)

        if upstream_fixed_versions_for_bz != []:
            fix_in = max([
                semantic_version.Version(v)
                for v in upstream_fixed_versions_for_bz
            ])
            BZs_fixed_by_version[str(fix_in)].add(bug.id)

    upstream_versions = [
        semantic_version.Version(v) for v in BZs_fixed_by_version.keys()
    ]
    upstream_versions.sort()  # Ensure in increasing order
    BZs_fixed_list = [BZs_fixed_by_version[str(v)] for v in upstream_versions]

    for i in range(1, len(BZs_fixed_list)):
        BZs_fixed_list[i] = BZs_fixed_list[i - 1] | BZs_fixed_list[i]

    for i, version in enumerate(upstream_versions):
        BZs_fixed_by_version[str(version)] = BZs_fixed_list[i]

    BZs_missing_by_version = {}
    for version, bugs in BZs_fixed_by_version.iteritems():
        BZs_missing_by_version[
            version] = all_BZs - BZs_fixed_by_version[version]

    minimum_version = semantic_version.Version(MINIMUM_VERSION)
    for v in upstream_versions:
        if v < minimum_version:
            continue
        bugs_in_this_version = BZs_missing_by_version[str(v)]
        print '%s, %s, https://bugzilla.redhat.com/buglist.cgi?quicksearch=%s' % (
            v, len(bugs_in_this_version), ','.join(
                [str(i) for i in bugs_in_this_version]))