Merge lp:~mvo/launchpad/support-timeframe-information into lp:launchpad/db-devel
- support-timeframe-information
- Merge into db-devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Michael Nelson | ||||
Approved revision: | no longer in the source branch. | ||||
Merged at revision: | not available | ||||
Proposed branch: | lp:~mvo/launchpad/support-timeframe-information | ||||
Merge into: | lp:launchpad/db-devel | ||||
Diff against target: |
245 lines (+161/-24) 2 files modified
cronscripts/publishing/cron.germinate (+1/-1) cronscripts/publishing/maintenance-check.py (+160/-23) |
||||
To merge this branch: | bzr merge lp:~mvo/launchpad/support-timeframe-information | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Nelson (community) | code | Approve | |
Michael Vogt (community) | Needs Resubmitting | ||
William Grant | code | Approve | |
Review via email: mp+22118@code.launchpad.net |
Commit message
Adds support for an additional "overwrite" file that can be used to tweak the support information generated during germination.
Description of the change
Please merge this updated support-
Michael Vogt (mvo) wrote : | # |
Aaron Bentley (abentley) wrote : | # |
The description does not give me enough context to do a review.
Michael Nelson (michael.nelson) wrote : | # |
Hi Michael!
Thanks for getting in there and improving Launchpad code!
As Aaron suggested, it would be really helpful to include more info with your merge proposal. A template we often try to use is:
https:/
or if you want lots of details ;) :
https:/
Especially important for branches like this without tests is a QA plan for how we can verify on dogfood that this does exactly what you intend. Tests would be wonderful, but I know that it's fair to ask you to add them now (If you want an example of how other cron scripts are tested, see lib/lp/
OK, I've got a bunch of small changes below, but more important for me is the summary of what this branch does (after reading it I've now understood most of it, but it would still be helpful to clarify) and steps for us to QA this on dogfood.
As I don't have lots of experience with germination etc. (I'm still learning ;) ), and Julian is away, I'll ask William to take a look to and provide feedback.
Thanks!
> === modified file 'cronscripts/
> --- cronscripts/
> +++ cronscripts/
> @@ -59,9 +63,57 @@
> # germinate output base directory
> BASE_URL = "http://
>
> +# hints dir url, hints file is "$distro.hints" by default
> +# (e.g. lucid.hints)
> +#HINTS_DIR_URL = "http://
Is there a reason for leaving the above comment eg. in?
> +HINTS_DIR_URL = "http://
> +
> +# we need the archive root to parse the Sources file to support
> +# by-source hints
> +#ARCHIVE_ROOT = "file:/
Same above?
> +ARCHIVE_ROOT = "http://
> +
> # support timeframe tag used in the Packages file
> SUPPORT_TAG = "Supported"
>
> +def get_binaries_
> + """
> + get all binary package names for the given source package name
> + """
Just a few style comments (based on the Launchpad python style guide at https:/
doesn't follow the style-guide, but it'd be nice to clean it up bit-by-bit
(but not necessary, up to you).
So the above docstring could be formatted along the lines of:
""" Return all binary names for the given source name."""
If you are really keen, you could add the :param: and :return: types as outlined under "Docstrings" in the above styleguide, but it's not necessary.
> + pkgnames = set()
> + recs = apt_pkg.
> + while recs.Lookup(
> + for binary in recs.Binaries:
> + pkgnames.
> + return pkgnames
> +
> +def expand_
> + """ expand a given pkgname if prefixed with src: to a list of
> + binary package names, if not prefixed, just return the pkgname
> + """
""" Expand a package...
William Grant (wgrant) wrote : | # |
The functionality seems good. Apart from the stylistic issues that noodles identified, this looks fine.
Michael Vogt (mvo) wrote : | # |
Many thanks for the review. I updated the branch now to cover most of your points.
Michael Vogt (mvo) wrote : | # |
The cover letter:
Summary:
Add ability to override seeds to make support information more accurate
Pre-implementation notes
For some package the seeds are not expressive enough, e.g. kvm is something we want to support for 5y, but the multimedia stack that is part of kvm and is not required to run kvm as a headless service (like libsdl) we only want to support for 3y.
Implementation details:
The implmentation adds the ability to override specific source or binary package support information.
Tests:
There are no unitests (yet). One test is running it and verifing that the output changes from:
libsdl1.
to 3y
Michael Nelson (michael.nelson) wrote : | # |
Thanks for the changes Michael. I spoke with Julian and he's ok without the tests this time, but would like to start always adding tests for this kind of thing. We'll need to run it on Dogfood before landing it.
Julian Edwards (julian-edwards) wrote : | # |
Hi
This can go in as it is, provided that it's tested on dogfood first. However, before any more non-urgent changes go in you should write unit tests please. If you need help with that, we'll be glad to assist.
Michael Nelson (michael.nelson) wrote : | # |
Tested initially on df with:
https:/
Michael will update the script so it doesn't depend on a newer version of python-apt.
Michael Vogt (mvo) wrote : | # |
I fixed this now to work with the python-apt version in hardy. Please give it another go.
Michael Nelson (michael.nelson) wrote : | # |
Great, thanks Michael!
Here's the output, please check if it's as you expected:
{{{
$ ./codelines/
hints-file: changing x11-common from 5y to 3y
hints-file: changing libsdl1.2debian from 5y to 3y
hints-file: changing libsdl1.
hints-file: changing libpulse0 from 5y to 3y
hints-file: changing libsndfile1 from 5y to 3y
hints-file: changing libogg0 from 5y to 3y
hints-file: changing libvorbis0a from 5y to 3y
hints-file: changing libvorbisenc2 from 5y to 3y
hints-file: changing libhal-storage1 from 5y to 3y
hints-file: changing libhal1 from 5y to 3y
hints-file: changing hal from 5y to 3y
hints-file: changing hal-info from 5y to 3y
}}}
But doing a diff on the before/after seems to just have *all* packages changed to 5y?
https:/
Michael Nelson (michael.nelson) wrote : | # |
OK, after chatting with mvo, I've run the script but *without* the server-ship change of r9154.
{{{
$ ./codelines/
hints-file: changing x11-common from 5y to 3y
}}}
and:
{{{
$ diff more-extra.
}}}
which gives
{{{
$ less more-extra.
903a904,906
> crypto-
> crypto-
> crypto-
3867a3871,3873
> kernel-
> kernel-
> kernel-
16272a16279,16281
> nic-shared-
> nic-shared-
> nic-shared-
17667a17677,17679
> ppp-modules-
> ppp-modules-
> ppp-modules-
19182a19195,19197
> serial-
> serial-
> serial-
20773,20774c207
< x11-common/i386 Supported 5y
< x11-common/amd64 Supported 5y
---
> x11-common/i386 Supported 3y
> x11-common/amd64 Supported 3y
}}}
Are those additional entries expected? If not I can re-run script without your changes to confirm.
Michael Nelson (michael.nelson) wrote : | # |
Approving after the above tests on dogfood.
Michael Nelson (michael.nelson) wrote : | # |
I meant to mention, although it's unrelated to your branch, when running the maintenance check for karmic the following happens on dogfood:
https:/
To find out why, I added the following:
{{{
=== modified file 'cronscripts/
--- cronscripts/
+++ cronscripts/
@@ -68,6 +68,8 @@
get structure file for named distro and distro version
(e.g. kubuntu, lucid)
"""
+ url = "%s/%s.
+ print url
f = urllib2.
structure = f.readlines()
f.close()
}}}
and the result is:
{{{
http://
http://
http://
http://
}}}
Michael Nelson (michael.nelson) wrote : | # |
JFTR: the above is expected by Michael:
12:28 <mvo> hello
12:28 <mvo> sorry for the slow reply, I was at lunch
12:29 <mvo> it needs to run post release for -updates and friends
12:30 <noodles> Great, as long as it's expected behavior.
Michael Nelson (michael.nelson) wrote : | # |
I created bug 562938 for the above.
Preview Diff
1 | === modified file 'cronscripts/publishing/cron.germinate' |
2 | --- cronscripts/publishing/cron.germinate 2010-03-02 09:58:34 +0000 |
3 | +++ cronscripts/publishing/cron.germinate 2010-04-13 12:58:27 +0000 |
4 | @@ -127,7 +127,7 @@ |
5 | echo " done." |
6 | |
7 | # now generate the Supported extra overrides |
8 | -$MAINTAINCE_CHECK $suite > "$MISCROOT/more-extra.override.$suite.main.supported" |
9 | +$MAINTAINCE_CHECK $suite > "$MISCROOT/more-extra.override.$suite.main.supported" 2> maintenance-check.stderr |
10 | if [ $? -eq 0 ]; then |
11 | cat "$MISCROOT/more-extra.override.$suite.main.supported" >> "$MISCROOT/more-extra.override.$suite.main.new" |
12 | fi |
13 | |
14 | === modified file 'cronscripts/publishing/maintenance-check.py' |
15 | --- cronscripts/publishing/maintenance-check.py 2010-04-12 15:13:53 +0000 |
16 | +++ cronscripts/publishing/maintenance-check.py 2010-04-13 12:58:27 +0000 |
17 | @@ -6,9 +6,19 @@ |
18 | # https://code.edge.launchpad.net/~mvo/ubuntu-maintenance-check/python-port |
19 | # (where it will vanish once taken here) |
20 | |
21 | +# this warning filter is only needed on older versions of python-apt, |
22 | +# once the machine runs lucid it can be removed |
23 | +import warnings |
24 | +warnings.filterwarnings("ignore","apt API not stable yet") |
25 | +import apt |
26 | +warnings.resetwarnings() |
27 | + |
28 | +import apt_pkg |
29 | import logging |
30 | +import os |
31 | import sys |
32 | import urllib2 |
33 | +import urlparse |
34 | |
35 | from optparse import OptionParser |
36 | |
37 | @@ -59,24 +69,98 @@ |
38 | # germinate output base directory |
39 | BASE_URL = "http://people.canonical.com/~ubuntu-archive/germinate-output/" |
40 | |
41 | +# hints dir url, hints file is "$distro.hints" by default |
42 | +# (e.g. lucid.hints) |
43 | +HINTS_DIR_URL = "http://people.canonical.com/~ubuntu-archive/seeds/platform.%s/SUPPORTED_HINTS" |
44 | + |
45 | +# we need the archive root to parse the Sources file to support |
46 | +# by-source hints |
47 | +ARCHIVE_ROOT = "http://archive.ubuntu.com/ubuntu" |
48 | + |
49 | # support timeframe tag used in the Packages file |
50 | SUPPORT_TAG = "Supported" |
51 | |
52 | - |
53 | -def get_structure(name, version): |
54 | - """ |
55 | - get structure file for named distro and distro version |
56 | - (e.g. kubuntu, lucid) |
57 | - """ |
58 | - f = urllib2.urlopen("%s/%s.%s/structure" % (BASE_URL, name, version)) |
59 | +def get_binaries_for_source_pkg(srcname): |
60 | + """ Return all binary package names for the given source package name. |
61 | + |
62 | + :param srcname: The source package name. |
63 | + :return: A list of binary package names. |
64 | + """ |
65 | + pkgnames = set() |
66 | + recs = apt_pkg.GetPkgSrcRecords() |
67 | + while recs.Lookup(srcname): |
68 | + for binary in recs.Binaries: |
69 | + pkgnames.add(binary) |
70 | + return pkgnames |
71 | + |
72 | +def expand_src_pkgname(pkgname): |
73 | + """ Expand a package name if it is prefixed with src. |
74 | + |
75 | + If the package name is prefixed with src it will be expanded |
76 | + to a list of binary package names. Otherwise the original |
77 | + package name will be returned. |
78 | + |
79 | + :param pkgname: The package name (that may include src:prefix). |
80 | + :return: A list of binary package names (the list may be one element long). |
81 | + """ |
82 | + if not pkgname.startswith("src:"): |
83 | + return [pkgname] |
84 | + return get_binaries_for_source_pkg(pkgname.split("src:")[1]) |
85 | + |
86 | +def create_and_update_deb_src_source_list(distroseries): |
87 | + """ Create sources.list and update cache. |
88 | + |
89 | + This creates a sources.list file with deb-src entries for a given |
90 | + distroseries and apt.Cache.update() to make sure the data is up-to-date. |
91 | + :param distro: The code name of the distribution series (e.g. lucid). |
92 | + :return: None |
93 | + :raises: IOError: When cache update fails. |
94 | + """ |
95 | + # apt root dir |
96 | + rootdir="./aptroot.%s" % distroseries |
97 | + sources_list_dir = os.path.join(rootdir, "etc","apt") |
98 | + if not os.path.exists(sources_list_dir): |
99 | + os.makedirs(sources_list_dir) |
100 | + sources_list = open(os.path.join(sources_list_dir, "sources.list"),"w") |
101 | + for pocket in [ |
102 | + "%s" % distroseries, |
103 | + "%s-updates" % distroseries, |
104 | + "%s-security" % distroseries]: |
105 | + sources_list.write( |
106 | + "deb-src %s %s main restricted\n" % ( |
107 | + ARCHIVE_ROOT, pocket)) |
108 | + sources_list.close() |
109 | + # create required dirs/files for apt.Cache(rootdir) to work on older |
110 | + # versions of python-apt. once lucid is used it can be removed |
111 | + for d in ["var/lib/dpkg", |
112 | + "var/cache/apt/archives/partial", |
113 | + "var/lib/apt/lists/partial"]: |
114 | + if not os.path.exists(os.path.join(rootdir,d)): |
115 | + os.makedirs(os.path.join(rootdir,d)) |
116 | + if not os.path.exists(os.path.join(rootdir,"var/lib/dpkg/status")): |
117 | + open(os.path.join(rootdir,"var/lib/dpkg/status"),"w") |
118 | + # open cache with our just prepared rootdir |
119 | + cache = apt.Cache(rootdir=rootdir) |
120 | + cache.update(apt.progress.FetchProgress()) |
121 | + |
122 | +def get_structure(distroname, version): |
123 | + """ Get structure file conent for named distro and distro version. |
124 | + |
125 | + :param name: Name of the distribution (e.g. kubuntu, ubuntu, xubuntu). |
126 | + :param version: Code name of the distribution version (e.g. lucid). |
127 | + :return: List of strings with the structure file content |
128 | + """ |
129 | + f = urllib2.urlopen("%s/%s.%s/structure" % (BASE_URL, distroname, version)) |
130 | structure = f.readlines() |
131 | f.close() |
132 | return structure |
133 | |
134 | def expand_seeds(structure, seedname): |
135 | - """ |
136 | - expand seed by its dependencies using the strucure file |
137 | - returns a set() for the seed dependencies (excluding the original seedname) |
138 | + """ Expand seed by its dependencies using the strucure file. |
139 | + |
140 | + :param structure: The content of the STRUCTURE file as string list. |
141 | + :param seedname: The name of the seed as string that needs to be expanded. |
142 | + :return: a set() for the seed dependencies (excluding the original seedname) |
143 | """ |
144 | seeds = [] |
145 | for line in structure: |
146 | @@ -150,6 +234,8 @@ |
147 | parser.add_option("--source-packages", "", default=False, |
148 | action="store_true", |
149 | help="show as source pkgs") |
150 | + parser.add_option("--hints-file", "", default=None, |
151 | + help="use diffenrt use hints file location") |
152 | (options, args) = parser.parse_args() |
153 | |
154 | # init |
155 | @@ -160,6 +246,17 @@ |
156 | sys.exit(1) |
157 | else: |
158 | distro = "lucid" |
159 | + |
160 | + # make sure our deb-src information is up-to-date |
161 | + create_and_update_deb_src_source_list(distro) |
162 | + |
163 | + if options.hints_file: |
164 | + hints_file = options.hints_file |
165 | + (schema, netloc, path, query, fragment) = urlparse.urlsplit(hints_file) |
166 | + if not schema: |
167 | + hints_file = "file:%s" % path |
168 | + else: |
169 | + hints_file = HINTS_DIR_URL % distro |
170 | |
171 | # go over the distros we need to check |
172 | pkg_support_time = {} |
173 | @@ -175,20 +272,60 @@ |
174 | else: |
175 | support_timeframe = SUPPORT_TIMEFRAME |
176 | get_packages_support_time(structure, name, pkg_support_time, support_timeframe) |
177 | + |
178 | + # now check the hints file that is used to overwrite |
179 | + # the default seeds |
180 | + try: |
181 | + for line in urllib2.urlopen(hints_file): |
182 | + line = line.strip() |
183 | + if not line or line.startswith("#"): |
184 | + continue |
185 | + try: |
186 | + (raw_pkgname, support_time) = line.split() |
187 | + for pkgname in expand_src_pkgname(raw_pkgname): |
188 | + if support_time == 'unsupported': |
189 | + try: |
190 | + del pkg_support_time[pkgname] |
191 | + sys.stderr.write("hints-file: marking %s unsupported\n" % pkgname) |
192 | + except KeyError: |
193 | + pass |
194 | + else: |
195 | + if pkg_support_time.get(pkgname) != support_time: |
196 | + sys.stderr.write( |
197 | + "hints-file: changing %s from %s to %s\n" % ( |
198 | + pkgname, pkg_support_time.get(pkgname), |
199 | + support_time)) |
200 | + pkg_support_time[pkgname] = support_time |
201 | + except: |
202 | + logging.exception("can not parse line '%s'" % line) |
203 | + except urllib2.HTTPError, e: |
204 | + if e.getcode() != 404: |
205 | + raise |
206 | + sys.stderr.write("hints-file: %s gave 404 error\n" % hints_file) |
207 | |
208 | # output suitable for the extra-override file |
209 | for pkgname in sorted(pkg_support_time.keys()): |
210 | - # go over the supported arches, they are divided in |
211 | - # first-class (PRIMARY) and second-class with different |
212 | - # support levels |
213 | - for arch in SUPPORTED_ARCHES: |
214 | - # full LTS support |
215 | - if arch in PRIMARY_ARCHES: |
216 | - print "%s/%s %s %s" % ( |
217 | - pkgname, arch, SUPPORT_TAG, pkg_support_time[pkgname]) |
218 | - else: |
219 | - # not a LTS supported architecture, gets only regular |
220 | - # support_timeframe |
221 | - print "%s/%s %s %s" % ( |
222 | - pkgname, arch, SUPPORT_TAG, SUPPORT_TIMEFRAME[0][0]) |
223 | + # special case, the hints file may contain overrides that |
224 | + # are arch-specific (like zsh-doc/armel) |
225 | + if "/" in pkgname: |
226 | + print "%s %s %s" % ( |
227 | + pkgname, SUPPORT_TAG, pkg_support_time[pkgname]) |
228 | + else: |
229 | + # go over the supported arches, they are divided in |
230 | + # first-class (PRIMARY) and second-class with different |
231 | + # support levels |
232 | + for arch in SUPPORTED_ARCHES: |
233 | + # ensure we do not overwrite arch-specific overwrites |
234 | + pkgname_and_arch = "%s/%s" % (pkgname, arch) |
235 | + if pkgname_and_arch in pkg_support_time: |
236 | + break |
237 | + if arch in PRIMARY_ARCHES: |
238 | + # arch with full LTS support |
239 | + print "%s %s %s" % ( |
240 | + pkgname_and_arch, SUPPORT_TAG, pkg_support_time[pkgname]) |
241 | + else: |
242 | + # not a LTS supported architecture, gets only regular |
243 | + # support_timeframe |
244 | + print "%s %s %s" % ( |
245 | + pkgname_and_arch, SUPPORT_TAG, SUPPORT_TIMEFRAME[0][0]) |
246 |
If it can be run on dogfood first to ensure it works properly in the LP environment, that would be most appreciated.