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

935.1.1 by Brian Murray
add in a wrapper for calling remove-package for SRUs that failed verification that also updates Launchpad bugs. Also add the tool's work to the -proposed cleanup in SRU report.
1
#!/usr/bin/python
2
3
# Copyright (C) 2015 Brian Murray <brian.murray@canonical.com>
4
5
# This program is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; version 3 of the License.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17
'''Remove an SRU fom the -proposed pocket for a release.
18
19
Remove a package from the -proposed pocket for a release of Ubuntu and comment
20
on bug reports regarding the removal of the package giving an explanation that
21
it was removed to due a failure for the SRU bug(s) to be verified in a timely
22
fashion.
23
24
USAGE:
25
    sru-remove -s trusty -p homerun 12345
26
'''
27
28
from __future__ import print_function
29
30
import optparse
31
import re
32
import subprocess
33
import sys
34
35
from launchpadlib.launchpad import Launchpad
36
37
38
def parse_options():
39
    '''Parse command line arguments.
40
41
    Return (options, [bugs]) tuple.
42
    '''
43
44
    parser = optparse.OptionParser(
1032 by Martin Pitt
sru-remove: fix confusing help, source_package is not a positional argument
45
        usage='Usage: %prog [options]')
935.1.1 by Brian Murray
add in a wrapper for calling remove-package for SRUs that failed verification that also updates Launchpad bugs. Also add the tool's work to the -proposed cleanup in SRU report.
46
    parser.add_option(
47
        "-l", "--launchpad", dest="launchpad_instance", default="production")
48
    parser.add_option(
49
        "-s", dest="release", default=default_release, metavar="RELEASE",
50
        help="release (default: %s)" % default_release)
51
    parser.add_option(
52
        "-p", "--package", dest="sourcepkg")
53
54
    opts, args = parser.parse_args()
55
56
    return (opts, args)
57
58
59
def process_bug(launchpad, distroseries, sourcepkg, num):
60
    bug_target_re = re.compile(
61
        r'/ubuntu/(?:(?P<suite>[^/]+)/)?\+source/(?P<source>[^/]+)$')
62
    bug = launchpad.bugs[num]
63
    series_name = distroseries.name
64
    open_task = False
65
66
    for task in bug.bug_tasks:
67
        # Ugly; we have to do URL-parsing to figure this out.
68
        # /ubuntu/+source/foo can be fed to launchpad.load() to get a
69
        # distribution_source_package, but /ubuntu/hardy/+source/foo can't.
70
        match = bug_target_re.search(task.target.self_link)
71
        if (not match or
72
            (sourcepkg and
73
             match.group('source') != sourcepkg)):
74
            print("Ignoring task %s in bug %s" % (task.web_link, num))
75
            continue
76
        if (match.group('suite') != series_name and
77
                match.group('suite') in supported_series and
78
                task.status == "Fix Committed"):
79
            open_task = True
80
        if (match.group('suite') == series_name and
81
                task.status == "Fix Committed"):
82
            task.status = "Won't Fix"
83
            task.lp_save()
84
            print("Success: task %s in bug %s" % (task.web_link, num))
85
        btags = bug.tags
86
        series_v_needed = 'verification-needed-%s' % series_name
87
        if series_v_needed in btags:
88
            # this dance is needed due to
89
            # https://bugs.launchpad.net/launchpadlib/+bug/254901
90
            tags = btags
91
            tags.remove(series_v_needed)
92
            bug.tags = tags
93
            bug.lp_save()
94
95
        text = ('The version of %s in the proposed pocket of %s that was '
96
                'purported to fix this bug report has been removed because '
97
                'the bugs that were to be fixed by the upload were not '
98
                'verified in a timely (105 days) fashion.' %
99
                (sourcepkg, series_name.title()))
100
        bug.newMessage(content=text,
101
                       subject='Proposed package removed from archive')
102
103
    # remove verification-needed tag if there are no open tasks
104
    if open_task:
105
        return
106
    # only unsubscribe the teams if there are no open tasks left
107
    bug.unsubscribe(person=launchpad.people['ubuntu-sru'])
108
    bug.unsubscribe(person=launchpad.people['sru-verification'])
109
    if 'verification-needed' in btags:
110
        # this dance is needed due to
111
        # https://bugs.launchpad.net/launchpadlib/+bug/254901
112
        tags = btags
113
        tags.remove('verification-needed')
114
        bug.tags = tags
115
        bug.lp_save()
116
117
118
if __name__ == '__main__':
119
1125 by Adam Conrad
artful -> bionic for devel; zesty -> artful for SRU
120
    default_release = 'artful'
935.1.1 by Brian Murray
add in a wrapper for calling remove-package for SRUs that failed verification that also updates Launchpad bugs. Also add the tool's work to the -proposed cleanup in SRU report.
121
    removal_comment = ('The package was removed due to its SRU bug(s) '
122
                       'not being verified in a timely fashion.')
123
124
    (opts, bugs) = parse_options()
125
126
    launchpad = Launchpad.login_with('sru-remove', opts.launchpad_instance,
127
                                     version="devel")
128
    ubuntu = launchpad.distributions['ubuntu']
129
    # determine series for which we issue SRUs
130
    supported_series = []
131
    for serie in ubuntu.series:
132
        if serie.supported:
133
            supported_series.append(serie.name)
134
135
    series = ubuntu.getSeries(name_or_version=opts.release)
136
    archive = ubuntu.main_archive
137
138
    existing = [
139
        pkg for pkg in archive.getPublishedSources(
140
            exact_match=True, distro_series=series, pocket='Proposed',
141
            source_name=opts.sourcepkg, status='Published')]
142
143
    if not existing:
144
        print("ERROR: %s was not found in -proposed for release %s." %
145
              (opts.sourcepkg, opts.release), file=sys.stderr)
146
        sys.exit(1)
147
148
    rm_p_cmd = ["remove-package", "-m", removal_comment, "-y",
149
                "-l", opts.launchpad_instance, "-s",
150
                "%s-proposed" % opts.release, opts.sourcepkg]
151
    ret = subprocess.call(rm_p_cmd)
152
    if ret != 0:
153
        print("ERROR: There was an error removing %s from %s-proposed.\n"
154
              "The remove-package command returned %s." %
155
              (opts.sourcepkg, opts.release, ret), file=sys.stderr)
156
        sys.exit(1)
157
    # only comment on the bugs after removing the package
158
    for bug in bugs:
159
        process_bug(launchpad, series, opts.sourcepkg, bug)