~launchpad-pqm/launchpad/devel

7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
1
#!/usr/bin/python
2
#
3
# python port of the nice maintainace-check script by  Nick Barcet
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
4
#
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
5
6
import logging
14564.3.1 by Jeroen Vermeulen
Lint.
7
from optparse import OptionParser
7675.633.2 by Michael Vogt
support src: prefix for src package hints
8
import os
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
9
import sys
10
import urllib2
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
11
import urlparse
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
12
14564.3.1 by Jeroen Vermeulen
Lint.
13
import apt
14
import apt_pkg
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
15
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
16
17
class UbuntuMaintenance(object):
18
    """ Represents the support timeframe for a regular ubuntu release """
14291.5.1 by Graham Binns
Cosmetic changes.
19
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
20
    # architectures that are full supported (including LTS time)
14291.5.1 by Graham Binns
Cosmetic changes.
21
    PRIMARY_ARCHES = [
22
        "i386",
23
        "amd64",
24
        ]
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
25
26
    # architectures we support (but not for LTS time)
27
    SUPPORTED_ARCHES = PRIMARY_ARCHES + ["armel"]
28
29
    # what defines the seeds is documented in wiki.ubuntu.com/SeedManagement
14291.5.1 by Graham Binns
Cosmetic changes.
30
    SERVER_SEEDS = [
31
        "server-ship",
32
        "supported-server",
33
        ]
34
    DESKTOP_SEEDS = [
35
        "ship",
36
        "supported-desktop",
37
        "supported-desktop-extra",
38
        ]
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
39
    SUPPORTED_SEEDS = ["all"]
40
41
    # normal support timeframe
42
    # time, seeds
43
    SUPPORT_TIMEFRAME = [
44
        ("18m", SUPPORTED_SEEDS),
45
        ]
46
14291.4.2 by Michael Vogt
simply DISTRO_NAMES_AND_LTS_SUPPORT as this is no longer needed in the old (and ugly) form
47
    # distro names that we check the seeds for
48
    DISTRO_NAMES = [
49
        "ubuntu",
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
50
        ]
51
14291.4.2 by Michael Vogt
simply DISTRO_NAMES_AND_LTS_SUPPORT as this is no longer needed in the old (and ugly) form
52
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
53
# This is fun! We have a bunch of cases for 10.04 LTS
54
#
55
#  - distro "ubuntu" follows SUPPORT_TIMEFRAME_LTS but only for
56
#    amd64/i386
57
#  - distros "kubuntu", "edubuntu" and "netbook" need to be
58
#    considered *but* only follow SUPPORT_TIMEFRAME
59
#  - anything that is in armel follows SUPPORT_TIMEFRAME
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
60
#
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
61
class LucidUbuntuMaintenance(UbuntuMaintenance):
14291.5.1 by Graham Binns
Cosmetic changes.
62
    """ Represents the support timeframe for a 10.04 (lucid) LTS release,
63
        the exact rules differ from LTS release to LTS release
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
64
    """
65
66
    # lts support timeframe, order is important, least supported must be last
67
    # time, seeds
68
    SUPPORT_TIMEFRAME = [
69
        ("5y",  UbuntuMaintenance.SERVER_SEEDS),
70
        ("3y",  UbuntuMaintenance.DESKTOP_SEEDS),
71
        ("18m", UbuntuMaintenance.SUPPORTED_SEEDS),
14291.5.1 by Graham Binns
Cosmetic changes.
72
        ]
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
73
14291.4.2 by Michael Vogt
simply DISTRO_NAMES_AND_LTS_SUPPORT as this is no longer needed in the old (and ugly) form
74
    # on a LTS this is significant, it defines what names get LTS support
75
    DISTRO_NAMES = [
14291.5.1 by Graham Binns
Cosmetic changes.
76
        "ubuntu",
14291.4.2 by Michael Vogt
simply DISTRO_NAMES_AND_LTS_SUPPORT as this is no longer needed in the old (and ugly) form
77
        "kubuntu",
14291.5.1 by Graham Binns
Cosmetic changes.
78
        ]
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
79
14291.4.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: make pep8 clean again (thanks to Colin for pointing this out)
80
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
81
class PreciseUbuntuMaintenance(UbuntuMaintenance):
82
    """ The support timeframe for the 12.04 (precise) LTS release.
83
        This changes the timeframe for desktop packages from 3y to 5y
84
    """
14291.4.4 by Michael Vogt
add compat code for old python-apt and to avoid deprecation warnings
85
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
86
    # lts support timeframe, order is important, least supported must be last
87
    # time, seeds
88
    SUPPORT_TIMEFRAME = [
89
        ("5y", UbuntuMaintenance.SERVER_SEEDS),
90
        ("5y", UbuntuMaintenance.DESKTOP_SEEDS),
91
        ("18m", UbuntuMaintenance.SUPPORTED_SEEDS),
14291.5.1 by Graham Binns
Cosmetic changes.
92
        ]
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
93
14291.4.2 by Michael Vogt
simply DISTRO_NAMES_AND_LTS_SUPPORT as this is no longer needed in the old (and ugly) form
94
    # on a LTS this is significant, it defines what names get LTS support
95
    DISTRO_NAMES = [
14291.5.1 by Graham Binns
Cosmetic changes.
96
        "ubuntu",
97
        ]
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
98
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
99
7675.1021.15 by Michael Vogt
cronscripts/publishing/maintenance-check.py: make unsupported release names explicit to avoid future problems when the codenames wrap around (thanks to Colin!)
100
# Names of the distribution releases that are not supported by this
101
# tool. All later versions are supported.
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
102
UNSUPPORTED_DISTRO_RELEASED = [
103
    "dapper",
104
    "edgy",
105
    "feisty",
106
    "gutsy",
107
    "hardy",
108
    "intrepid",
109
    "jaunty",
110
    "karmic",
111
    ]
7675.1021.15 by Michael Vogt
cronscripts/publishing/maintenance-check.py: make unsupported release names explicit to avoid future problems when the codenames wrap around (thanks to Colin!)
112
113
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
114
# germinate output base directory
7675.1021.29 by Michael Vogt
cronscripts/publishing/maintenance-check.py: support url overrides in the environment for {MAINTENANCE_CHECK_BASE_URL, MAINTENANCE_CHECK_HINTS_DIR_URL, MAINTENANCE_CHECK_ARCHIVE_ROOT}
115
BASE_URL = os.environ.get(
14514.3.2 by Colin Watson
Lint.
116
    "MAINTENANCE_CHECK_BASE_URL",
7675.1021.29 by Michael Vogt
cronscripts/publishing/maintenance-check.py: support url overrides in the environment for {MAINTENANCE_CHECK_BASE_URL, MAINTENANCE_CHECK_HINTS_DIR_URL, MAINTENANCE_CHECK_ARCHIVE_ROOT}
117
    "http://people.canonical.com/~ubuntu-archive/germinate-output/")
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
118
7675.633.2 by Michael Vogt
support src: prefix for src package hints
119
# hints dir url, hints file is "$distro.hints" by default
120
# (e.g. lucid.hints)
7675.1021.29 by Michael Vogt
cronscripts/publishing/maintenance-check.py: support url overrides in the environment for {MAINTENANCE_CHECK_BASE_URL, MAINTENANCE_CHECK_HINTS_DIR_URL, MAINTENANCE_CHECK_ARCHIVE_ROOT}
121
HINTS_DIR_URL = os.environ.get(
14514.3.2 by Colin Watson
Lint.
122
    "MAINTENANCE_CHECK_HINTS_DIR_URL",
14564.3.1 by Jeroen Vermeulen
Lint.
123
    "http://people.canonical.com/"
124
        "~ubuntu-archive/seeds/platform.%s/SUPPORTED_HINTS")
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
125
7675.633.2 by Michael Vogt
support src: prefix for src package hints
126
# we need the archive root to parse the Sources file to support
127
# by-source hints
7675.1021.29 by Michael Vogt
cronscripts/publishing/maintenance-check.py: support url overrides in the environment for {MAINTENANCE_CHECK_BASE_URL, MAINTENANCE_CHECK_HINTS_DIR_URL, MAINTENANCE_CHECK_ARCHIVE_ROOT}
128
ARCHIVE_ROOT = os.environ.get(
129
    "MAINTENANCE_CHECK_ARCHIVE_ROOT", "http://archive.ubuntu.com/ubuntu")
7675.633.2 by Michael Vogt
support src: prefix for src package hints
130
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
131
# support timeframe tag used in the Packages file
132
SUPPORT_TAG = "Supported"
133
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
134
7675.633.2 by Michael Vogt
support src: prefix for src package hints
135
def get_binaries_for_source_pkg(srcname):
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
136
    """ Return all binary package names for the given source package name.
137
138
    :param srcname: The source package name.
139
    :return: A list of binary package names.
7675.633.2 by Michael Vogt
support src: prefix for src package hints
140
    """
141
    pkgnames = set()
14514.3.1 by Colin Watson
Port to new python-apt API.
142
    recs = apt_pkg.SourceRecords()
143
    while recs.lookup(srcname):
144
        for binary in recs.binaries:
7675.633.2 by Michael Vogt
support src: prefix for src package hints
145
            pkgnames.add(binary)
146
    return pkgnames
147
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
148
7675.633.2 by Michael Vogt
support src: prefix for src package hints
149
def expand_src_pkgname(pkgname):
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
150
    """ Expand a package name if it is prefixed with src.
151
152
    If the package name is prefixed with src it will be expanded
153
    to a list of binary package names. Otherwise the original
154
    package name will be returned.
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
155
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
156
    :param pkgname: The package name (that may include src:prefix).
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
157
    :return: A list of binary package names (the list may be one element
158
             long).
7675.633.2 by Michael Vogt
support src: prefix for src package hints
159
    """
160
    if not pkgname.startswith("src:"):
161
        return [pkgname]
162
    return get_binaries_for_source_pkg(pkgname.split("src:")[1])
163
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
164
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
165
def create_and_update_deb_src_source_list(distroseries):
166
    """ Create sources.list and update cache.
167
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
168
    This creates a sources.list file with deb-src entries for a given
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
169
    distroseries and apt.Cache.update() to make sure the data is up-to-date.
170
    :param distro: The code name of the distribution series (e.g. lucid).
171
    :return: None
172
    :raises: IOError: When cache update fails.
7675.633.2 by Michael Vogt
support src: prefix for src package hints
173
    """
174
    # apt root dir
7675.1021.21 by Michael Vogt
cronscripts/publishing/tests/test_cron.germinate.py, cronscripts/publishing/maintenance-check.py: add SPACE around "=" to follow LP coding standard
175
    rootdir = "./aptroot.%s" % distroseries
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
176
    sources_list_dir = os.path.join(rootdir, "etc", "apt")
7675.633.2 by Michael Vogt
support src: prefix for src package hints
177
    if not os.path.exists(sources_list_dir):
178
        os.makedirs(sources_list_dir)
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
179
    sources_list = open(os.path.join(sources_list_dir, "sources.list"), "w")
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
180
    for pocket in [
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
181
        "%s" % distroseries,
182
        "%s-updates" % distroseries,
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
183
        "%s-security" % distroseries]:
184
        sources_list.write(
185
            "deb-src %s %s main restricted\n" % (
7675.633.2 by Michael Vogt
support src: prefix for src package hints
186
                ARCHIVE_ROOT, pocket))
7675.642.4 by Michael Vogt
cronscripts/publishing/maintenance-check.py: collect leftover packages in main that are not in a seed. there shouldn't be any, but there are some
187
        sources_list.write(
188
            "deb %s %s main restricted\n" % (
189
                ARCHIVE_ROOT, pocket))
7675.633.2 by Michael Vogt
support src: prefix for src package hints
190
    sources_list.close()
7675.633.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: create required dirs/files in rootdir (for older python-apt versions)
191
    # create required dirs/files for apt.Cache(rootdir) to work on older
192
    # versions of python-apt. once lucid is used it can be removed
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
193
    for d in ["var/lib/dpkg",
194
              "var/cache/apt/archives/partial",
195
              "var/lib/apt/lists/partial"]:
196
        if not os.path.exists(os.path.join(rootdir, d)):
197
            os.makedirs(os.path.join(rootdir, d))
198
    if not os.path.exists(os.path.join(rootdir, "var/lib/dpkg/status")):
199
        open(os.path.join(rootdir, "var/lib/dpkg/status"), "w")
7675.633.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: create required dirs/files in rootdir (for older python-apt versions)
200
    # open cache with our just prepared rootdir
7675.633.2 by Michael Vogt
support src: prefix for src package hints
201
    cache = apt.Cache(rootdir=rootdir)
7675.642.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: log update() errors (caused e.g. by proxies) but continue, its ok to have slightly outdated data)
202
    try:
14514.3.1 by Colin Watson
Port to new python-apt API.
203
        cache.update()
7675.642.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: log update() errors (caused e.g. by proxies) but continue, its ok to have slightly outdated data)
204
    except SystemError:
205
        logging.exception("cache.update() failed")
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
206
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
207
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
208
def get_structure(distroname, version):
209
    """ Get structure file conent for named distro and distro version.
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
210
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
211
    :param name: Name of the distribution (e.g. kubuntu, ubuntu, xubuntu).
212
    :param version: Code name of the distribution version (e.g. lucid).
213
    :return: List of strings with the structure file content
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
214
    """
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
215
    f = urllib2.urlopen("%s/%s.%s/structure" % (
216
            BASE_URL, distroname, version))
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
217
    structure = f.readlines()
218
    f.close()
219
    return structure
220
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
221
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
222
def expand_seeds(structure, seedname):
14564.3.1 by Jeroen Vermeulen
Lint.
223
    """Expand seed by its dependencies using the strucure file.
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
224
225
    :param structure: The content of the STRUCTURE file as string list.
226
    :param seedname: The name of the seed as string that needs to be expanded.
14564.3.1 by Jeroen Vermeulen
Lint.
227
    :return: A set() for the seed dependencies (excluding the original
228
        seedname).
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
229
    """
230
    seeds = []
231
    for line in structure:
232
        if line.startswith("%s:" % seedname):
233
            seeds += line.split(":")[1].split()
234
            for seed in seeds:
235
                seeds += expand_seeds(structure, seed)
236
    return set(seeds)
237
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
238
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
239
def get_packages_for_seeds(name, distro, seeds):
240
    """
14564.3.1 by Jeroen Vermeulen
Lint.
241
    Get packages for the given name (e.g. ubuntu) and distro release
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
242
    (e.g. lucid) that are in the given list of seeds
14564.3.1 by Jeroen Vermeulen
Lint.
243
    returns a set() of package names.
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
244
    """
245
    pkgs_in_seeds = {}
14564.3.1 by Jeroen Vermeulen
Lint.
246
    for seed in seeds:
247
        pkgs_in_seeds[seed] = set()
248
        seedurl = "%s/%s.%s/%s" % (BASE_URL, name, distro, seed)
249
        logging.debug("looking for '%s'", seedurl)
250
        try:
251
            f = urllib2.urlopen(seedurl)
252
            for line in f:
253
                # Ignore lines that are not package names (headers etc).
254
                if line[0] < 'a' or line[0] > 'z':
255
                    continue
256
                # Each line contains these fields:
257
                # (package, source, why, maintainer, size, inst-size)
258
                if options.source_packages:
259
                    pkgname = line.split("|")[1]
260
                else:
261
                    pkgname = line.split("|")[0]
262
                pkgs_in_seeds[seed].add(pkgname.strip())
263
            f.close()
264
        except Exception as e:
265
            logging.error("seed %s failed (%s)" % (seedurl, e))
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
266
    return pkgs_in_seeds
267
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
268
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
269
def what_seeds(pkgname, seeds):
270
    in_seeds = set()
271
    for s in seeds:
272
        if pkgname in seeds[s]:
273
            in_seeds.add(s)
274
    return in_seeds
275
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
276
7675.642.2 by Michael Vogt
cronscripts/publishing/maintenance-check.py: deal properly with packages in multiple seeds that have different support levels (pick the highest support level than)
277
def compare_support_level(x, y):
278
    """
279
    compare two support level strings of the form 18m, 3y etc
280
    :parm x: the first support level
281
    :parm y: the second support level
282
    :return: negative if x < y, zero if x==y, positive if x > y
283
    """
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
284
7675.642.2 by Michael Vogt
cronscripts/publishing/maintenance-check.py: deal properly with packages in multiple seeds that have different support levels (pick the highest support level than)
285
    def support_to_int(support_time):
286
        """
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
287
        helper that takes a support time string and converts it to
7675.642.2 by Michael Vogt
cronscripts/publishing/maintenance-check.py: deal properly with packages in multiple seeds that have different support levels (pick the highest support level than)
288
        a integer for cmp()
289
        """
290
        # allow strings like "5y (kubuntu-common)
291
        x = support_time.split()[0]
292
        if x.endswith("y"):
293
            return 12 * int(x[0:-1])
294
        elif x.endswith("m"):
295
            return int(x[0:-1])
296
        else:
297
            raise ValueError("support time '%s' has to end with y or m" % x)
298
    return cmp(support_to_int(x), support_to_int(y))
299
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
300
301
def get_packages_support_time(structure, name, pkg_support_time,
302
                              support_timeframe_list):
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
303
    """
304
    input a structure file and a list of pair<timeframe, seedlist>
305
    return a dict of pkgnames -> support timeframe string
306
    """
307
    for (timeframe, seedlist) in support_timeframe_list:
308
        expanded = set()
309
        for s in seedlist:
310
            expanded.add(s)
311
            expanded |= expand_seeds(structure, s)
312
        pkgs_in_seeds = get_packages_for_seeds(name, distro, expanded)
313
        for seed in pkgs_in_seeds:
314
            for pkg in pkgs_in_seeds[seed]:
315
                if not pkg in pkg_support_time:
316
                    pkg_support_time[pkg] = timeframe
7675.642.2 by Michael Vogt
cronscripts/publishing/maintenance-check.py: deal properly with packages in multiple seeds that have different support levels (pick the highest support level than)
317
                else:
318
                    old_timeframe = pkg_support_time[pkg]
319
                    if compare_support_level(old_timeframe, timeframe) < 0:
320
                        logging.debug("overwriting %s from %s to %s" % (
321
                                pkg, old_timeframe, timeframe))
322
                        pkg_support_time[pkg] = timeframe
323
                if options.with_seeds:
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
324
                    pkg_support_time[pkg] += " (%s)" % ", ".join(
325
                        what_seeds(pkg, pkgs_in_seeds))
7675.642.2 by Michael Vogt
cronscripts/publishing/maintenance-check.py: deal properly with packages in multiple seeds that have different support levels (pick the highest support level than)
326
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
327
    return pkg_support_time
328
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
329
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
330
if __name__ == "__main__":
331
    parser = OptionParser()
332
    parser.add_option("--with-seeds", "", default=False,
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
333
                      action="store_true",
334
                      help="add seed(s) of the package that are responsible "
335
                           "for the maintaince time")
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
336
    parser.add_option("--source-packages", "", default=False,
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
337
                      action="store_true",
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
338
                      help="show as source pkgs")
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
339
    parser.add_option("--hints-file", "", default=None,
340
                      help="use diffenrt use hints file location")
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
341
    (options, args) = parser.parse_args()
342
343
    # init
344
    if len(args) > 0:
345
        distro = args[0]
7675.1021.15 by Michael Vogt
cronscripts/publishing/maintenance-check.py: make unsupported release names explicit to avoid future problems when the codenames wrap around (thanks to Colin!)
346
        if distro in UNSUPPORTED_DISTRO_RELEASED:
7675.1021.2 by Michael Vogt
remove all binary data from the tree and generate it on the fly
347
            logging.error("only lucid or later is supported")
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
348
            sys.exit(1)
349
    else:
350
        distro = "lucid"
14291.5.1 by Graham Binns
Cosmetic changes.
351
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
352
    # maintenance class to use
353
    klass = globals().get("%sUbuntuMaintenance" % distro.capitalize())
354
    if klass is None:
355
        klass = UbuntuMaintenance
356
    ubuntu_maintenance = klass()
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
357
7675.633.2 by Michael Vogt
support src: prefix for src package hints
358
    # make sure our deb-src information is up-to-date
359
    create_and_update_deb_src_source_list(distro)
360
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
361
    if options.hints_file:
362
        hints_file = options.hints_file
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
363
        (schema, netloc, path, query, fragment) = urlparse.urlsplit(
364
            hints_file)
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
365
        if not schema:
366
            hints_file = "file:%s" % path
367
    else:
7675.633.3 by Michael Vogt
update hints file location, add hints overwrite information to maintenance-check.stderr output
368
        hints_file = HINTS_DIR_URL % distro
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
369
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
370
    # go over the distros we need to check
371
    pkg_support_time = {}
14291.4.2 by Michael Vogt
simply DISTRO_NAMES_AND_LTS_SUPPORT as this is no longer needed in the old (and ugly) form
372
    for name in ubuntu_maintenance.DISTRO_NAMES:
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
373
374
        # get basic structure file
7675.1021.2 by Michael Vogt
remove all binary data from the tree and generate it on the fly
375
        try:
376
            structure = get_structure(name, distro)
377
        except urllib2.HTTPError:
7675.1021.7 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix missing capitalization and punctation and kill off whitespace
378
            logging.error("Can not get structure for '%s'." % name)
7675.1021.2 by Michael Vogt
remove all binary data from the tree and generate it on the fly
379
            continue
7675.1021.7 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix missing capitalization and punctation and kill off whitespace
380
7675.481.5 by Michael Vogt
add armel case and proper checking for all of main
381
        # get dicts of pkgname -> support timeframe string
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
382
        support_timeframe = ubuntu_maintenance.SUPPORT_TIMEFRAME
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
383
        get_packages_support_time(
384
            structure, name, pkg_support_time, support_timeframe)
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
385
7675.642.4 by Michael Vogt
cronscripts/publishing/maintenance-check.py: collect leftover packages in main that are not in a seed. there shouldn't be any, but there are some
386
    # now go over the bits in main that we have not seen (because
387
    # they are not in any seed and got added manually into "main"
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
388
    for arch in ubuntu_maintenance.PRIMARY_ARCHES:
14291.4.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: make pep8 clean again (thanks to Colin for pointing this out)
389
        rootdir = "./aptroot.%s" % distro
14514.3.1 by Colin Watson
Port to new python-apt API.
390
        apt_pkg.config.set("APT::Architecture", arch)
7675.642.4 by Michael Vogt
cronscripts/publishing/maintenance-check.py: collect leftover packages in main that are not in a seed. there shouldn't be any, but there are some
391
        cache = apt.Cache(rootdir=rootdir)
7675.642.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: log update() errors (caused e.g. by proxies) but continue, its ok to have slightly outdated data)
392
        try:
14514.3.1 by Colin Watson
Port to new python-apt API.
393
            cache.update()
7675.642.8 by Michael Vogt
cronscripts/publishing/maintenance-check.py: log update() errors (caused e.g. by proxies) but continue, its ok to have slightly outdated data)
394
        except SystemError:
395
            logging.exception("cache.update() failed")
14514.3.1 by Colin Watson
Port to new python-apt API.
396
        cache.open()
7675.642.4 by Michael Vogt
cronscripts/publishing/maintenance-check.py: collect leftover packages in main that are not in a seed. there shouldn't be any, but there are some
397
        for pkg in cache:
14291.4.3 by Michael Vogt
cronscripts/publishing/maintenance-check.py: ignore multiarch pkg names when iterating the cache
398
            # ignore multiarch package names
399
            if ":" in pkg.name:
400
                continue
7675.642.4 by Michael Vogt
cronscripts/publishing/maintenance-check.py: collect leftover packages in main that are not in a seed. there shouldn't be any, but there are some
401
            if not pkg.name in pkg_support_time:
402
                pkg_support_time[pkg.name] = support_timeframe[-1][0]
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
403
                logging.warn(
404
                    "add package in main but not in seeds %s with %s" % (
405
                        pkg.name, pkg_support_time[pkg.name]))
7675.642.4 by Michael Vogt
cronscripts/publishing/maintenance-check.py: collect leftover packages in main that are not in a seed. there shouldn't be any, but there are some
406
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
407
    # now check the hints file that is used to overwrite
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
408
    # the default seeds
409
    try:
410
        for line in urllib2.urlopen(hints_file):
411
            line = line.strip()
412
            if not line or line.startswith("#"):
413
                continue
414
            try:
7675.633.2 by Michael Vogt
support src: prefix for src package hints
415
                (raw_pkgname, support_time) = line.split()
416
                for pkgname in expand_src_pkgname(raw_pkgname):
417
                    if support_time == 'unsupported':
7675.633.3 by Michael Vogt
update hints file location, add hints overwrite information to maintenance-check.stderr output
418
                        try:
419
                            del pkg_support_time[pkgname]
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
420
                            sys.stderr.write("hints-file: marking %s "
421
                                             "unsupported\n" % pkgname)
7675.633.3 by Michael Vogt
update hints file location, add hints overwrite information to maintenance-check.stderr output
422
                        except KeyError:
423
                            pass
7675.633.2 by Michael Vogt
support src: prefix for src package hints
424
                    else:
7675.633.3 by Michael Vogt
update hints file location, add hints overwrite information to maintenance-check.stderr output
425
                        if pkg_support_time.get(pkgname) != support_time:
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
426
                            sys.stderr.write(
427
                                "hints-file: changing %s from %s to %s\n" % (
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
428
                                    pkgname, pkg_support_time.get(pkgname),
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
429
                                    support_time))
7675.633.3 by Michael Vogt
update hints file location, add hints overwrite information to maintenance-check.stderr output
430
                            pkg_support_time[pkgname] = support_time
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
431
            except:
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
432
                logging.exception("can not parse line '%s'" % line)
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
433
    except urllib2.HTTPError, e:
7675.720.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: urllib2.HTTPError has a code attribute, getcode() is only available for the old urllib
434
        if e.code != 404:
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
435
            raise
7675.633.5 by Michael Vogt
cronscripts/publishing/maintenance-check.py: updated for final hints filename/destination, add debug outout if hints_file is not found
436
        sys.stderr.write("hints-file: %s gave 404 error\n" % hints_file)
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
437
7675.481.1 by Michael Vogt
* lib/lp/soyuz/scripts/maintenance-check.py:
438
    # output suitable for the extra-override file
439
    for pkgname in sorted(pkg_support_time.keys()):
7675.633.7 by Michael Vogt
address points raised in review (many thanks)
440
        # special case, the hints file may contain overrides that
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
441
        # are arch-specific (like zsh-doc/armel)
442
        if "/" in pkgname:
443
            print "%s %s %s" % (
444
                pkgname, SUPPORT_TAG, pkg_support_time[pkgname])
445
        else:
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
446
            # go over the supported arches, they are divided in
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
447
            # first-class (PRIMARY) and second-class with different
448
            # support levels
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
449
            for arch in ubuntu_maintenance.SUPPORTED_ARCHES:
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
450
                # ensure we do not overwrite arch-specific overwrites
451
                pkgname_and_arch = "%s/%s" % (pkgname, arch)
452
                if pkgname_and_arch in pkg_support_time:
453
                    break
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
454
                if arch in ubuntu_maintenance.PRIMARY_ARCHES:
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
455
                    # arch with full LTS support
456
                    print "%s %s %s" % (
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
457
                        pkgname_and_arch, SUPPORT_TAG,
458
                        pkg_support_time[pkgname])
7675.633.1 by Michael Vogt
cronscripts/publishing/maintenance-check.py: add support for a ".binary-hints" file that can be used to overwrite the seed support timeframe
459
                else:
460
                    # not a LTS supported architecture, gets only regular
461
                    # support_timeframe
462
                    print "%s %s %s" % (
7675.1021.18 by Michael Vogt
cronscripts/publishing/maintenance-check.py: fix pocketlint errors (spacing, indent, linewrap)
463
                        pkgname_and_arch, SUPPORT_TAG,
14291.4.1 by Michael Vogt
refactor to allow different support timeframes on each lts (as precise is different from lucid). testsed with diff -u of the old-code output for lucid against the new code output for lucid
464
                        ubuntu_maintenance.SUPPORT_TIMEFRAME[-1][0])