~xnox/ubuntu-archive-tools/sru-report-autopkgtest-vomit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/python

# Copyright (C) 2012 Canonical, Ltd.
# Author: Brian Murray <brian@canonical.com>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

# given a release find all the packages published in proposed and
# search each package for bug tasks about the package reported
# since the date the package was uploaded to proposed for apport and release
# tagged bugs that contain the version of the package from -proposed

from __future__ import print_function

import optparse

from launchpadlib.launchpad import Launchpad

try:
    from urllib.request import urlopen
except ImportError:
    from urllib import urlopen


def bugs_from_changes(change_url):
    '''Return (bug_list, cve_list) from a .changes file URL'''
    changelog = urlopen(change_url)

    refs = []
    bugs = set()

    for l in changelog:
        if l.startswith('Launchpad-Bugs-Fixed: '):
            refs = l.split()[1:]
            break

    for b in refs:
        try:
            lpbug = lp.bugs[int(b)]
        except KeyError:
            continue
        bugs.add(lpbug)

    return sorted(bugs)


if __name__ == '__main__':

    APPORT_TAGS = (
        'apport-package',
        'apport-bug',
        'apport-crash',
        'apport-kerneloops',
    )

    lp = Launchpad.login_with(
        'ubuntu-archive-tools', 'production', version='devel')

    ubuntu = lp.distributions['ubuntu']
    archive = ubuntu.getArchive(name='primary')

    parser = optparse.OptionParser(usage="usage: %prog --release RELEASE")
    parser.add_option('--release', help='', dest='release')

    (opt, args) = parser.parse_args()

    releases = {}
    if not opt.release:
        for series in ubuntu.series:
            if not series.supported:
                continue
            if series.active:
                releases[series.name] = series
    else:
        series = ubuntu.getSeries(name_or_version=opt.release)
        releases[series.name] = series

    for release in sorted(releases):
        print('Release: %s' % release)
        for spph in archive.getPublishedSources(
                pocket='Proposed', status='Published',
                distro_series=releases[release]):
            package_name = spph.source_package_name
            # for langpack updates, only keep -en as a representative
            # cargo-culted from sru-report
            if (package_name.startswith('language-pack-') and
                package_name not in ('language-pack-en',
                                     'language-pack-en-base')):
                continue
            date_pub = spph.date_published
            version = spph.source_package_version
            change_url = spph.changesFileUrl()

            if not change_url:
                print("Package %s has no changes file url")
                continue

            package = ubuntu.getSourcePackage(name=package_name)
            tasks = []
            # search for bugs reported by apport
            for tag in APPORT_TAGS:
                for task in package.searchTasks(
                        tags=[tag, release], created_since=date_pub,
                        tags_combinator='All'):
                    tasks.append(task)
            # also search for ones tagged regression-proposed
            for task in package.searchTasks(
                    tags=['regression-proposed', release],
                    created_since=date_pub, tags_combinator='All'):
                tasks.append(task)

            for task in tasks:
                if version not in task.bug.description:
                    continue
                sru_bugs = bugs_from_changes(change_url)
                # check to see if any of the sru bugs are already tagged
                # verification-failed
                v_failed = False
                for sru_bug in sru_bugs:
                    if 'verification-failed' in sru_bug.tags:
                        print('  The SRU for package %s already has a '
                              'verification-failed bug in LP: #%s' %
                              (package_name, sru_bug.id))
                        v_failed = True
                bug = task.bug
                if not v_failed and set(APPORT_TAGS).intersection(bug.tags):
                    print('  LP: #%s is regarding %s from -proposed' %
                          (bug.id, package_name))
                elif not v_failed:
                    print('  LP: #%s is regarding %s from -proposed and '
                          'tagged regression-proposed' %
                          (bug.id, package_name))