~laney/ubuntu-archive-tools/cm-show-fix-released

248 by Martin Pitt
add sru-release
1
#!/usr/bin/python
355 by Colin Watson
Apply GPLv3 to anything not already licensed; ok slangasek, broder, laney, kitterman, geser
2
3
# Copyright (C) 2011, 2012 Canonical Ltd.
248 by Martin Pitt
add sru-release
4
# Author: Martin Pitt <martin.pitt@canonical.com>
5
355 by Colin Watson
Apply GPLv3 to anything not already licensed; ok slangasek, broder, laney, kitterman, geser
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; version 3 of the License.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
248 by Martin Pitt
add sru-release
18
'''Release a proposed stable release update.
19
20
Copy packages from -proposed to -updates, and optionally to -security and the
21
development release.
22
23
USAGE:
24
   sru-release [-s] [-d] <release> <package> [<package> ...]
25
'''
26
386 by Colin Watson
sru-release: add "from __future__ import print_function", needed for "print()" to work properly
27
from __future__ import print_function
28
555 by Colin Watson
Simplify using collections.defaultdict.
29
from collections import defaultdict
557 by Colin Watson
sru-release: reduce duplication using functools.partial
30
from functools import partial
351 by Colin Watson
Replace lputils with direct calls to Launchpad.login_with or Launchpad.login_anonymously as appropriate.
31
import optparse
248 by Martin Pitt
add sru-release
32
import sys
351 by Colin Watson
Replace lputils with direct calls to Launchpad.login_with or Launchpad.login_anonymously as appropriate.
33
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
34
try:
35
    from urllib.request import urlopen
36
except ImportError:
37
    from urllib import urlopen
38
351 by Colin Watson
Replace lputils with direct calls to Launchpad.login_with or Launchpad.login_anonymously as appropriate.
39
from launchpadlib.launchpad import Launchpad
248 by Martin Pitt
add sru-release
40
492 by Colin Watson
sort imports
41
684 by Colin Watson
sru-release: add --exclude-bug option
42
def match_srubugs(options, changesfileurl):
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
43
    '''match between bugs with verification- tag and bugs in changesfile'''
44
45
    bugs = []
46
47
    if changesfileurl is None:
48
        return bugs
49
50
    # Load changesfile
51
    changelog = urlopen(changesfileurl)
52
    bugnums = []
53
    for l in changelog:
54
        if l.startswith('Launchpad-Bugs-Fixed: '):
55
            bugnums = l.split()[1:]
56
            break
57
58
    for b in bugnums:
684 by Colin Watson
sru-release: add --exclude-bug option
59
        if b in options.exclude_bug:
60
            continue
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
61
        try:
62
            bugs.append(launchpad.bugs[int(b)])
63
        except:
558 by Colin Watson
PEP-8
64
            print('%s: bug %s does not exist or is not accessible' %
65
                  (changesfileurl, b))
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
66
67
    return bugs
68
558 by Colin Watson
PEP-8
69
795.1.1 by Brian Murray
sru-release: add in package name when commenting on verified SRUs
70
def update_sru_bug(bug, pkg):
558 by Colin Watson
PEP-8
71
    '''Unsubscribe SRU team and comment on bug re: how to report regressions'''
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
72
    m_subjects = [m.subject for m in bug.messages]
73
    if 'Update Released' in m_subjects:
773.1.1 by Brian Murray
sru-release: clarifying that is a comment that is not made not status / importance changes
74
        print('LP: #%s was not commented on' % bug.id)
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
75
        return
76
    sru_team = launchpad.people['ubuntu-sru']
77
    bug.unsubscribe(person=sru_team)
795.1.1 by Brian Murray
sru-release: add in package name when commenting on verified SRUs
78
    text = ("The verification of the Stable Release Update for %s has "
79
            "completed successfully and the package has now been released "
80
            "to -updates.  Subsequently, the Ubuntu Stable Release Updates "
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
81
            "Team is being unsubscribed and will not receive messages "
82
            "about this bug report.  In the event that you encounter "
83
            "a regression using the package from -updates please report "
84
            "a new bug using ubuntu-bug and tag the bug report "
839 by Colin Watson
typo
85
            "regression-update so we can easily find any regressions." % pkg)
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
86
    bug.newMessage(subject="Update Released", content=text)
87
    bug.lp_save()
88
558 by Colin Watson
PEP-8
89
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
90
def get_versions(options, sourcename):
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
91
    '''Get current package versions.
92
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
93
    If options.pattern is True, return all versions for package names
94
    matching options.pattern.
95
    If options.pattern is False, only return one result.
274 by Colin Watson
remove trailing whitespace
96
97
    Return map pkgname -> {'release': version, 'updates': version,
98
      'proposed': version, 'changesfile': url_of_proposed_changes,
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
99
      'published': proposed_date}
248 by Martin Pitt
add sru-release
100
    '''
555 by Colin Watson
Simplify using collections.defaultdict.
101
    versions = defaultdict(dict)
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
102
    matches = archive.getPublishedSources(
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
103
        source_name=sourcename, exact_match=not options.pattern,
104
        status='Published', pocket='Proposed', distro_series=series)
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
105
    for match in matches:
106
        # versions in all pockets
545 by Colin Watson
Make all scripts pass pep8(1).
107
        for pub in archive.getPublishedSources(
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
108
                source_name=match.source_package_name, exact_match=True,
109
                status='Published', distro_series=series):
555 by Colin Watson
Simplify using collections.defaultdict.
110
            versions[pub.source_package_name][pub.pocket.lower()] = (
111
                pub.source_package_version)
554 by Brian Murray
sru-release: comment on bugs when releasing packages to -updates and unsubscribe the SRU team from those bugs
112
            if 'Proposed' in pub.pocket:
558 by Colin Watson
PEP-8
113
                versions[pub.source_package_name]['changesfile'] = (
114
                    pub.changesFileUrl())
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
115
        # devel version
116
        if devel_series:
545 by Colin Watson
Make all scripts pass pep8(1).
117
            for pub in archive.getPublishedSources(
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
118
                    source_name=match.source_package_name, exact_match=True,
119
                    status='Published', distro_series=devel_series):
655 by Colin Watson
sru-release: make -d copy to <devel>-proposed, not <devel>
120
                if pub.pocket in ('Release', 'Proposed'):
121
                    versions[pub.source_package_name]['devel'] = (
122
                        pub.source_package_version)
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
123
        else:
124
            versions[match.source_package_name]['devel'] = None
248 by Martin Pitt
add sru-release
125
126
    return versions
127
545 by Colin Watson
Make all scripts pass pep8(1).
128
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
129
def release_package(options, package):
248 by Martin Pitt
add sru-release
130
    '''Release a package.'''
131
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
132
    pkg_versions_map = get_versions(options, package)
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
133
    if not pkg_versions_map:
870 by Scott Kitterman
Inlude name of non-existing package when sru-release fails due to 'No such package ...'.
134
        message = 'ERROR: No such package, ' + package + ', in -proposed, aborting\n'
135
        sys.stderr.write(message)
248 by Martin Pitt
add sru-release
136
        sys.exit(1)
137
364 by Colin Watson
dict.keys/dict.items -> dict.iterkeys/dict.iteritems when used as an iterable
138
    for pkg, versions in pkg_versions_map.iteritems():
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
139
        print('--- Releasing %s ---' % pkg)
140
        print('Proposed: %s' % versions['proposed'])
141
        if 'security' in versions:
142
            print('Security: %s' % versions['security'])
143
        if 'updates' in versions:
144
            print('Updates:  %s' % versions['updates'])
145
        else:
146
            print('Release:  %s' % versions.get('release'))
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
147
        if options.devel and 'devel' in versions:
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
148
            print('Devel:    %s' % versions['devel'])
149
557 by Colin Watson
sru-release: reduce duplication using functools.partial
150
        copy = partial(
151
            archive.copyPackage, from_archive=archive, include_binaries=True,
560 by Colin Watson
auto-sync, copy-proposed-kernel, sru-release: automatically approve copies
152
            source_name=pkg, version=versions['proposed'], auto_approve=True)
557 by Colin Watson
sru-release: reduce duplication using functools.partial
153
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
154
        if options.devel:
545 by Colin Watson
Make all scripts pass pep8(1).
155
            if ('devel' not in versions or
156
                versions['devel'] in (
157
                    versions.get('updates', 'notexisting'),
158
                    versions['release'])):
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
159
                if not options.no_act:
655 by Colin Watson
sru-release: make -d copy to <devel>-proposed, not <devel>
160
                    copy(to_pocket='Proposed', to_series=devel_series.name)
545 by Colin Watson
Make all scripts pass pep8(1).
161
                print('Version in %s matches development series, '
655 by Colin Watson
sru-release: make -d copy to <devel>-proposed, not <devel>
162
                      'copied to %s-proposed' % (release, devel_series.name))
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
163
            else:
545 by Colin Watson
Make all scripts pass pep8(1).
164
                print('ERROR: Version in %s does not match development '
165
                      'series, not copying' % release)
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
166
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
167
        if options.no_act:
168
            if options.release:
390 by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release
169
                print('Would copy to %s' % release)
170
            else:
171
                print('Would copy to %s-updates' % release)
172
        else:
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
173
            if options.release:
609 by Colin Watson
sru-release: fix comment
174
                # -proposed -> release
557 by Colin Watson
sru-release: reduce duplication using functools.partial
175
                copy(to_pocket='Release', to_series=release)
390 by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release
176
                print('Copied to %s' % release)
177
            else:
178
                # -proposed -> -updates
825 by Colin Watson
sru-release: update comment about which releases are phased
179
                # only phasing updates for >=raring to start
878 by Colin Watson
sru-release: drop support for quantal
180
                if (release not in ('lucid', 'precise') and
776.1.2 by Brian Murray
sru-release: modify logic for release checking for setting p-u-p
181
                        not options.security):
764.1.1 by Brian Murray
sru-release: phased updates are being started with raring
182
                    copy(to_pocket='Updates', to_series=release,
833.1.1 by Brian Murray
sru-release: add an option to specify the phased_update_percentage
183
                         phased_update_percentage=options.percentage)
764.1.1 by Brian Murray
sru-release: phased updates are being started with raring
184
                else:
185
                    copy(to_pocket='Updates', to_series=release)
390 by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release
186
                print('Copied to %s-updates' % release)
836 by Adam Conrad
sru-release: Add --no-bugs option
187
                if not options.no_bugs:
188
                    sru_bugs = match_srubugs(options, versions['changesfile'])
189
                    for sru_bug in sru_bugs:
190
                        if 'verification-needed' not in sru_bug.tags:
191
                            update_sru_bug(sru_bug, pkg)
258 by Martin Pitt
sru-release: add -p/--pattern option, mostly useful for "language-pack-"
192
193
        # -proposed -> -security
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
194
        if options.security:
195
            if options.no_act:
390 by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release
196
                print('Would copy to %s-security' % release)
197
            else:
557 by Colin Watson
sru-release: reduce duplication using functools.partial
198
                copy(to_pocket='Security', to_series=release)
390 by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release
199
                print('Copied to %s-security' % release)
248 by Martin Pitt
add sru-release
200
545 by Colin Watson
Make all scripts pass pep8(1).
201
248 by Martin Pitt
add sru-release
202
if __name__ == '__main__':
545 by Colin Watson
Make all scripts pass pep8(1).
203
    parser = optparse.OptionParser(
204
        usage='usage: %prog [options] <release> <package> [<package> ...]')
248 by Martin Pitt
add sru-release
205
545 by Colin Watson
Make all scripts pass pep8(1).
206
    parser.add_option(
207
        '-l', '--launchpad', dest='launchpad_instance', default='production')
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
208
    parser.add_option(
731 by Colin Watson
sru-release: drop short option -s for --security; too easily confused with --suite/--series in other tools
209
        '--security', action='store_true', default=False,
545 by Colin Watson
Make all scripts pass pep8(1).
210
        help='Additionally copy to -security pocket')
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
211
    parser.add_option(
212
        '-d', '--devel', action='store_true', default=False,
545 by Colin Watson
Make all scripts pass pep8(1).
213
        help='Additionally copy to development release (only works if that '
214
             'has the same version as <release>)')
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
215
    parser.add_option(
216
        '-r', '--release', action='store_true', default=False,
545 by Colin Watson
Make all scripts pass pep8(1).
217
        help='Copy to release pocket instead of -updates (useful for staging '
218
             'uploads in development release)')
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
219
    parser.add_option(
833.1.1 by Brian Murray
sru-release: add an option to specify the phased_update_percentage
220
        "-z", "--percentage", type="int", default=10,
221
        metavar="PERCENTAGE", help="set phased update percentage")
222
    parser.add_option(
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
223
        '-n', '--no-act', action='store_true', default=False,
545 by Colin Watson
Make all scripts pass pep8(1).
224
        help='Only perform checks, but do not actually copy packages')
677 by Colin Watson
make all scripts pass current stricter pep8(1) in raring
225
    parser.add_option(
226
        '-p', '--pattern', action='store_true', default=False,
545 by Colin Watson
Make all scripts pass pep8(1).
227
        help='Treat package names as patterns, not exact matches')
684 by Colin Watson
sru-release: add --exclude-bug option
228
    parser.add_option(
836 by Adam Conrad
sru-release: Add --no-bugs option
229
        '--no-bugs', action='store_true', default=False,
230
        help='Do not act on any bugs (helpful to avoid races).')
231
    parser.add_option(
684 by Colin Watson
sru-release: add --exclude-bug option
232
        '--exclude-bug', action='append', default=[], metavar='BUG',
233
        help='Do not update BUG.')
248 by Martin Pitt
add sru-release
234
235
    options, args = parser.parse_args()
236
237
    if len(args) < 2:
545 by Colin Watson
Make all scripts pass pep8(1).
238
        parser.error(
239
            'You must specify a release and source package(s), see --help')
248 by Martin Pitt
add sru-release
240
390 by Martin Pitt
sru-release: Add --release/-r option for copying to release pocket, for staging uploads in development release
241
    if options.release and (options.security or options.devel):
242
        parser.error('-r and -s/-d are mutually exclusive, see --help')
243
248 by Martin Pitt
add sru-release
244
    release = args.pop(0)
245
    packages = args
246
372 by Colin Watson
sru-release: use Archive.copyPackage (asynchronous) rather than Archive.syncSource (synchronous), which should avoid timeouts
247
    launchpad = Launchpad.login_with(
395 by Colin Watson
sru-release: add -l/--launchpad option
248
        'ubuntu-archive-tools', options.launchpad_instance, version='devel')
248 by Martin Pitt
add sru-release
249
    ubuntu = launchpad.distributions['ubuntu']
250
    series = ubuntu.getSeries(name_or_version=release)
408 by Martin Pitt
sru-release: use ubuntu.current_series instead of ubuntu.getDevelopmentSeries(), as that also covers frozen releases
251
    devel_series = ubuntu.current_series
252
    if not devel_series:
545 by Colin Watson
Make all scripts pass pep8(1).
253
        sys.stderr.write(
254
            'WARNING: No current development series, -d will not work\n')
248 by Martin Pitt
add sru-release
255
        devel_series = None
256
    archive = ubuntu.getArchive(name='primary')
257
258
    for package in packages:
683 by Colin Watson
sru-release: pass options object rather than passing lots of individual bits of it
259
        release_package(options, package)