Merge lp:~wgrant/launchpad/refactor-_dominateBinary into lp:launchpad
- refactor-_dominateBinary
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Robert Collins |
Approved revision: | no longer in the source branch. |
Merged at revision: | 11181 |
Proposed branch: | lp:~wgrant/launchpad/refactor-_dominateBinary |
Merge into: | lp:launchpad |
Diff against target: |
753 lines (+184/-226) 9 files modified
lib/lp/archivepublisher/domination.py (+49/-179) lib/lp/archivepublisher/tests/test_dominator.py (+13/-15) lib/lp/registry/doc/distroseries.txt (+3/-3) lib/lp/soyuz/doc/archive.txt (+2/-7) lib/lp/soyuz/doc/distroarchseries.txt (+2/-3) lib/lp/soyuz/doc/publishing.txt (+2/-10) lib/lp/soyuz/interfaces/publishing.py (+19/-6) lib/lp/soyuz/model/publishing.py (+91/-1) lib/lp/soyuz/scripts/ftpmaster.py (+3/-2) |
To merge this branch: | bzr merge lp:~wgrant/launchpad/refactor-_dominateBinary |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Collins (community) | Approve | ||
Review via email: mp+29667@code.launchpad.net |
Commit message
Move per-publication Dominator logic into the model.
Description of the change
This branch shuffles lots of logic from lp.archivepublisher into the model. The diff is horrific, I admit, but the files have ended up much cleaner than before.
Package domination is currently performed by lp.archivepubli
This branch moves the logic from _dominateBinary and _dominateSource into [SB]PPH.supersede, letting Dominator just identify candidates and call a single method on each to let them handle themselves.
SPPH.supersede is simple: it checks that the publication can be superseded, then calls the base method (setting datesuperseded and status), and sets supersededby if a dominant publication is provided.
BPPH.supersede does the same, but also incorporates additional functionality from _dominateBinar*
With all that code ripped out into the model, some duplication was revealed in Dominator. A couple of methods had distinct source and binary versions, with only simple attribute name differences. I've merged them by passing around a couple of attrgetters. Not pretty, but better than duplicating the code.
All this brings huge potential for test cleanups. But this branch is big enough, so another (slightly oversized) test rewrite branch follows.
Preview Diff
1 | === modified file 'lib/lp/archivepublisher/domination.py' | |||
2 | --- lib/lp/archivepublisher/domination.py 2010-05-18 10:30:12 +0000 | |||
3 | +++ lib/lp/archivepublisher/domination.py 2010-07-20 09:44:57 +0000 | |||
4 | @@ -52,9 +52,12 @@ | |||
5 | 52 | 52 | ||
6 | 53 | __all__ = ['Dominator'] | 53 | __all__ = ['Dominator'] |
7 | 54 | 54 | ||
8 | 55 | import apt_pkg | ||
9 | 56 | from datetime import timedelta | 55 | from datetime import timedelta |
10 | 56 | import functools | ||
11 | 57 | import gc | 57 | import gc |
12 | 58 | import operator | ||
13 | 59 | |||
14 | 60 | import apt_pkg | ||
15 | 58 | 61 | ||
16 | 59 | from lp.archivepublisher import ELIGIBLE_DOMINATION_STATES | 62 | from lp.archivepublisher import ELIGIBLE_DOMINATION_STATES |
17 | 60 | from canonical.database.constants import UTC_NOW | 63 | from canonical.database.constants import UTC_NOW |
18 | @@ -73,38 +76,23 @@ | |||
19 | 73 | clear_current_connection_cache() | 76 | clear_current_connection_cache() |
20 | 74 | gc.collect() | 77 | gc.collect() |
21 | 75 | 78 | ||
22 | 76 | PENDING = PackagePublishingStatus.PENDING | ||
23 | 77 | PUBLISHED = PackagePublishingStatus.PUBLISHED | ||
24 | 78 | SUPERSEDED = PackagePublishingStatus.SUPERSEDED | ||
25 | 79 | DELETED = PackagePublishingStatus.DELETED | ||
26 | 80 | OBSOLETE = PackagePublishingStatus.OBSOLETE | ||
27 | 81 | 79 | ||
28 | 82 | # Ugly, but works | 80 | # Ugly, but works |
29 | 83 | apt_pkg.InitSystem() | 81 | apt_pkg.InitSystem() |
30 | 84 | 82 | ||
54 | 85 | def _compare_source_packages_by_version_and_date(p1, p2): | 83 | |
55 | 86 | """Compare packages p1 and p2 by their version; using Debian rules. | 84 | def _compare_packages_by_version_and_date(get_release, p1, p2): |
56 | 87 | 85 | """Compare publications p1 and p2 by their version; using Debian rules. | |
57 | 88 | If the comparison is the same sourcepackagerelease, compare by datecreated | 86 | |
58 | 89 | instead. So later records beat earlier ones. | 87 | If the publications are for the same package, compare by datecreated |
59 | 90 | """ | 88 | instead. This lets newer records win. |
60 | 91 | if p1.sourcepackagerelease.id == p2.sourcepackagerelease.id: | 89 | """ |
61 | 92 | return cmp(p1.datecreated, p2.datecreated) | 90 | if get_release(p1).id == get_release(p2).id: |
62 | 93 | 91 | return cmp(p1.datecreated, p2.datecreated) | |
63 | 94 | return apt_pkg.VersionCompare(p1.sourcepackagerelease.version, | 92 | |
64 | 95 | p2.sourcepackagerelease.version) | 93 | return apt_pkg.VersionCompare(get_release(p1).version, |
65 | 96 | 94 | get_release(p2).version) | |
66 | 97 | def _compare_binary_packages_by_version_and_date(p1, p2): | 95 | |
44 | 98 | """Compare packages p1 and p2 by their version; using Debian rules | ||
45 | 99 | |||
46 | 100 | If the comparison is the same binarypackagerelease, compare by datecreated | ||
47 | 101 | instead. So later records beat earlier ones. | ||
48 | 102 | """ | ||
49 | 103 | if p1.binarypackagerelease.id == p2.binarypackagerelease.id: | ||
50 | 104 | return cmp(p1.datecreated, p2.datecreated) | ||
51 | 105 | |||
52 | 106 | return apt_pkg.VersionCompare(p1.binarypackagerelease.version, | ||
53 | 107 | p2.binarypackagerelease.version) | ||
67 | 108 | 96 | ||
68 | 109 | class Dominator: | 97 | class Dominator: |
69 | 110 | """ Manage the process of marking packages as superseded. | 98 | """ Manage the process of marking packages as superseded. |
70 | @@ -123,131 +111,22 @@ | |||
71 | 123 | self.archive = archive | 111 | self.archive = archive |
72 | 124 | self.debug = self._logger.debug | 112 | self.debug = self._logger.debug |
73 | 125 | 113 | ||
199 | 126 | def _dominateSource(self, sourceinput): | 114 | def _dominatePublications(self, pubs): |
200 | 127 | """ | 115 | """Perform dominations for the given publications. |
201 | 128 | Perform dominations for source. | 116 | |
202 | 129 | """ | 117 | :param pubs: A dict mapping names to a list of publications. Every |
203 | 130 | self.debug("Dominating sources...") | 118 | publication must be PUBLISHED or PENDING, and the first in each |
204 | 131 | for sourcename in sourceinput.keys(): | 119 | list will be treated as dominant (so should be the latest). |
205 | 132 | # source is a list of versions ordered most-recent-first | 120 | """ |
206 | 133 | # basically skip the first entry because that is | 121 | self.debug("Dominating packages...") |
207 | 134 | # never dominated by us, then just set subsequent entries | 122 | |
208 | 135 | # to SUPERSEDED unless they're already there or pending | 123 | for name in pubs.keys(): |
209 | 136 | # removal | 124 | assert pubs[name], ( |
210 | 137 | assert sourceinput[sourcename], ( | 125 | "Empty list of publications for %s" % name) |
211 | 138 | "Empty list of publications for %s" % sourcename) | 126 | for pubrec in pubs[name][1:]: |
212 | 139 | super_release = sourceinput[sourcename][0].sourcepackagerelease | 127 | pubrec.supersede(pubs[name][0], self) |
213 | 140 | super_release_name = super_release.sourcepackagename.name | 128 | |
214 | 141 | for pubrec in sourceinput[sourcename][1:]: | 129 | def _sortPackages(self, pkglist, is_source=True): |
90 | 142 | if pubrec.status == PUBLISHED or pubrec.status == PENDING: | ||
91 | 143 | this_release = pubrec.sourcepackagerelease | ||
92 | 144 | |||
93 | 145 | this_release_name = this_release.sourcepackagename.name | ||
94 | 146 | self.debug( | ||
95 | 147 | "%s/%s has been judged as superseded by %s/%s" % | ||
96 | 148 | (this_release_name, this_release.version, | ||
97 | 149 | super_release_name, super_release.version)) | ||
98 | 150 | |||
99 | 151 | pubrec.status = SUPERSEDED | ||
100 | 152 | pubrec.datesuperseded = UTC_NOW | ||
101 | 153 | pubrec.supersededby = super_release | ||
102 | 154 | |||
103 | 155 | def _getOtherBinaryPublications(self, dominated): | ||
104 | 156 | """Return remaining publications of the same binarypackagerelease. | ||
105 | 157 | |||
106 | 158 | It only considers binary publications in the same distroseries, | ||
107 | 159 | pocket and archive context, which is the limit where the domination | ||
108 | 160 | should happen. | ||
109 | 161 | |||
110 | 162 | Return only binaries published or pending in the same component, | ||
111 | 163 | section and priority, this way the just-made override will be | ||
112 | 164 | preserved. | ||
113 | 165 | """ | ||
114 | 166 | # Avoid circular imports. | ||
115 | 167 | from lp.soyuz.model.publishing import ( | ||
116 | 168 | BinaryPackagePublishingHistory) | ||
117 | 169 | |||
118 | 170 | dominated_series = dominated.distroarchseries.distroseries | ||
119 | 171 | available_architectures = [ | ||
120 | 172 | das.id for das in dominated_series.architectures] | ||
121 | 173 | query = """ | ||
122 | 174 | BinaryPackagePublishingHistory.status IN %s AND | ||
123 | 175 | BinaryPackagePublishingHistory.distroarchseries IN %s AND | ||
124 | 176 | BinaryPackagePublishingHistory.binarypackagerelease = %s AND | ||
125 | 177 | BinaryPackagePublishingHistory.pocket = %s AND | ||
126 | 178 | BinaryPackagePublishingHistory.archive = %s AND | ||
127 | 179 | BinaryPackagePublishingHistory.component = %s AND | ||
128 | 180 | BinaryPackagePublishingHistory.section = %s AND | ||
129 | 181 | BinaryPackagePublishingHistory.priority = %s | ||
130 | 182 | """ % sqlvalues([PUBLISHED, PENDING], available_architectures, | ||
131 | 183 | dominated.binarypackagerelease, dominated.pocket, | ||
132 | 184 | dominated.archive, dominated.component, | ||
133 | 185 | dominated.section, dominated.priority) | ||
134 | 186 | return BinaryPackagePublishingHistory.select(query) | ||
135 | 187 | |||
136 | 188 | def _dominateBinary(self, dominated, dominant): | ||
137 | 189 | """Dominate the given binarypackagerelease publication.""" | ||
138 | 190 | # At this point only PUBLISHED (ancient versions) or PENDING ( | ||
139 | 191 | # multiple overrides/copies) publications should be given. We | ||
140 | 192 | # tolerate SUPERSEDED architecture-independent binaries, because | ||
141 | 193 | # they are dominated automatically once the first publication is | ||
142 | 194 | # processed. | ||
143 | 195 | if dominated.status not in [PUBLISHED, PENDING]: | ||
144 | 196 | arch_independent = ( | ||
145 | 197 | dominated.binarypackagerelease.architecturespecific == False) | ||
146 | 198 | assert arch_independent, ( | ||
147 | 199 | "Should not dominate unpublished architecture specific " | ||
148 | 200 | "binary %s (%s)" % ( | ||
149 | 201 | dominated.binarypackagerelease.title, | ||
150 | 202 | dominated.distroarchseries.architecturetag)) | ||
151 | 203 | return | ||
152 | 204 | |||
153 | 205 | dominant_build = dominant.binarypackagerelease.build | ||
154 | 206 | distroarchseries = dominant_build.distro_arch_series | ||
155 | 207 | self.debug( | ||
156 | 208 | "The %s build of %s has been judged as superseded by the build " | ||
157 | 209 | "of %s. Arch-specific == %s" % ( | ||
158 | 210 | distroarchseries.architecturetag, | ||
159 | 211 | dominated.binarypackagerelease.title, | ||
160 | 212 | dominant.binarypackagerelease.build.source_package_release.title, | ||
161 | 213 | dominated.binarypackagerelease.architecturespecific)) | ||
162 | 214 | dominated.status = SUPERSEDED | ||
163 | 215 | dominated.datesuperseded = UTC_NOW | ||
164 | 216 | # Binary package releases are superseded by the new build, | ||
165 | 217 | # not the new binary package release. This is because | ||
166 | 218 | # there may not *be* a new matching binary package - | ||
167 | 219 | # source packages can change the binaries they build | ||
168 | 220 | # between releases. | ||
169 | 221 | dominated.supersededby = dominant_build | ||
170 | 222 | |||
171 | 223 | def _dominateBinaries(self, binaryinput): | ||
172 | 224 | """Perform dominations for binaries.""" | ||
173 | 225 | self.debug("Dominating binaries...") | ||
174 | 226 | for binaryname in binaryinput.keys(): | ||
175 | 227 | # binary is a list of versions ordered most-recent-first | ||
176 | 228 | # basically skip the first entry because that is | ||
177 | 229 | # never dominated by us, then just set subsequent entries | ||
178 | 230 | # to SUPERSEDED unless they're already there or pending | ||
179 | 231 | # removal | ||
180 | 232 | assert binaryinput[binaryname], ( | ||
181 | 233 | "Empty list of publications for %s" % binaryname) | ||
182 | 234 | # At some future point, this code might automatically locate | ||
183 | 235 | # binaries which are no longer built from source (NBS). | ||
184 | 236 | # Currently this is done in archive cruft check. | ||
185 | 237 | dominant = binaryinput[binaryname][0] | ||
186 | 238 | for dominated in binaryinput[binaryname][1:]: | ||
187 | 239 | # Dominate all publications of architecture independent | ||
188 | 240 | # binaries altogether in this distroseries and pocket. | ||
189 | 241 | if not dominated.binarypackagerelease.architecturespecific: | ||
190 | 242 | other_publications = self._getOtherBinaryPublications( | ||
191 | 243 | dominated) | ||
192 | 244 | for dominated in other_publications: | ||
193 | 245 | self._dominateBinary(dominated, dominant) | ||
194 | 246 | else: | ||
195 | 247 | self._dominateBinary(dominated, dominant) | ||
196 | 248 | |||
197 | 249 | |||
198 | 250 | def _sortPackages(self, pkglist, isSource=True): | ||
215 | 251 | # pkglist is a list of packages with the following | 130 | # pkglist is a list of packages with the following |
216 | 252 | # * sourcepackagename or packagename as appropriate | 131 | # * sourcepackagename or packagename as appropriate |
217 | 253 | # * version | 132 | # * version |
218 | @@ -255,32 +134,22 @@ | |||
219 | 255 | # Don't care about any other attributes | 134 | # Don't care about any other attributes |
220 | 256 | outpkgs = {} | 135 | outpkgs = {} |
221 | 257 | 136 | ||
226 | 258 | if isSource: | 137 | self.debug("Sorting packages...") |
227 | 259 | self.debug("Sorting sources...") | 138 | |
228 | 260 | else: | 139 | attr_prefix = 'source' if is_source else 'binary' |
229 | 261 | self.debug("Sorting binaries...") | 140 | get_release = operator.attrgetter(attr_prefix + 'packagerelease') |
230 | 141 | get_name = operator.attrgetter(attr_prefix + 'packagename') | ||
231 | 262 | 142 | ||
232 | 263 | for inpkg in pkglist: | 143 | for inpkg in pkglist: |
242 | 264 | if isSource: | 144 | L = outpkgs.setdefault( |
243 | 265 | L = outpkgs.setdefault( | 145 | get_name(get_release(inpkg)).name.encode('utf-8'), []) |
235 | 266 | inpkg.sourcepackagerelease.sourcepackagename.name.encode( | ||
236 | 267 | 'utf-8'), []) | ||
237 | 268 | else: | ||
238 | 269 | L = outpkgs.setdefault( | ||
239 | 270 | inpkg.binarypackagerelease.binarypackagename.name.encode( | ||
240 | 271 | 'utf-8'), []) | ||
241 | 272 | |||
244 | 273 | L.append(inpkg) | 146 | L.append(inpkg) |
245 | 274 | 147 | ||
246 | 275 | for pkgname in outpkgs: | 148 | for pkgname in outpkgs: |
247 | 276 | if len(outpkgs[pkgname]) > 1: | 149 | if len(outpkgs[pkgname]) > 1: |
255 | 277 | if isSource: | 150 | outpkgs[pkgname].sort( |
256 | 278 | outpkgs[pkgname].sort( | 151 | functools.partial( |
257 | 279 | _compare_source_packages_by_version_and_date) | 152 | _compare_packages_by_version_and_date, get_release)) |
251 | 280 | else: | ||
252 | 281 | outpkgs[pkgname].sort( | ||
253 | 282 | _compare_binary_packages_by_version_and_date) | ||
254 | 283 | |||
258 | 284 | outpkgs[pkgname].reverse() | 153 | outpkgs[pkgname].reverse() |
259 | 285 | 154 | ||
260 | 286 | return outpkgs | 155 | return outpkgs |
261 | @@ -443,11 +312,12 @@ | |||
262 | 443 | binarypackagerelease.id | 312 | binarypackagerelease.id |
263 | 444 | AND binarypackagerelease.binarypackagename IN ( | 313 | AND binarypackagerelease.binarypackagename IN ( |
264 | 445 | SELECT name FROM PubDomHelper WHERE count > 1)""" | 314 | SELECT name FROM PubDomHelper WHERE count > 1)""" |
267 | 446 | % sqlvalues (distroarchseries, self.archive, | 315 | % sqlvalues(distroarchseries, self.archive, |
268 | 447 | pocket, PackagePublishingStatus.PUBLISHED), | 316 | pocket, PackagePublishingStatus.PUBLISHED), |
269 | 448 | clauseTables=['BinaryPackageRelease']) | 317 | clauseTables=['BinaryPackageRelease']) |
270 | 449 | 318 | ||
272 | 450 | self._dominateBinaries(self._sortPackages(binaries, False)) | 319 | self.debug("Dominating binaries...") |
273 | 320 | self._dominatePublications(self._sortPackages(binaries, False)) | ||
274 | 451 | if do_clear_cache: | 321 | if do_clear_cache: |
275 | 452 | self.debug("Flushing SQLObject cache.") | 322 | self.debug("Flushing SQLObject cache.") |
276 | 453 | clear_cache() | 323 | clear_cache() |
277 | @@ -464,7 +334,8 @@ | |||
278 | 464 | sources = SourcePackagePublishingHistory.selectBy( | 334 | sources = SourcePackagePublishingHistory.selectBy( |
279 | 465 | distroseries=dr, archive=self.archive, pocket=pocket, | 335 | distroseries=dr, archive=self.archive, pocket=pocket, |
280 | 466 | status=PackagePublishingStatus.PUBLISHED) | 336 | status=PackagePublishingStatus.PUBLISHED) |
282 | 467 | self._dominateSource(self._sortPackages(sources)) | 337 | self.debug("Dominating sources...") |
283 | 338 | self._dominatePublications(self._sortPackages(sources)) | ||
284 | 468 | flush_database_updates() | 339 | flush_database_updates() |
285 | 469 | 340 | ||
286 | 470 | sources = SourcePackagePublishingHistory.select(""" | 341 | sources = SourcePackagePublishingHistory.select(""" |
287 | @@ -492,4 +363,3 @@ | |||
288 | 492 | 363 | ||
289 | 493 | self.debug("Domination for %s/%s finished" % | 364 | self.debug("Domination for %s/%s finished" % |
290 | 494 | (dr.name, pocket.title)) | 365 | (dr.name, pocket.title)) |
291 | 495 | |||
292 | 496 | 366 | ||
293 | === modified file 'lib/lp/archivepublisher/tests/test_dominator.py' | |||
294 | --- lib/lp/archivepublisher/tests/test_dominator.py 2010-07-18 00:24:06 +0000 | |||
295 | +++ lib/lp/archivepublisher/tests/test_dominator.py 2010-07-20 09:44:57 +0000 | |||
296 | @@ -75,7 +75,7 @@ | |||
297 | 75 | # and dominated, the subsequents. | 75 | # and dominated, the subsequents. |
298 | 76 | source_input = {'foo': [dominant_source, dominated_source]} | 76 | source_input = {'foo': [dominant_source, dominated_source]} |
299 | 77 | 77 | ||
301 | 78 | dominator._dominateSource(source_input) | 78 | dominator._dominatePublications(source_input) |
302 | 79 | flush_database_updates() | 79 | flush_database_updates() |
303 | 80 | 80 | ||
304 | 81 | # The dominant version remains correctly published. | 81 | # The dominant version remains correctly published. |
305 | @@ -96,7 +96,7 @@ | |||
306 | 96 | dominator = Dominator(self.logger, self.ubuntutest.main_archive) | 96 | dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
307 | 97 | source_input = {'foo': []} | 97 | source_input = {'foo': []} |
308 | 98 | self.assertRaises( | 98 | self.assertRaises( |
310 | 99 | AssertionError, dominator._dominateSource, source_input) | 99 | AssertionError, dominator._dominatePublications, source_input) |
311 | 100 | 100 | ||
312 | 101 | def testBinariesDomination(self): | 101 | def testBinariesDomination(self): |
313 | 102 | """Test overall binary domination procedure.""" | 102 | """Test overall binary domination procedure.""" |
314 | @@ -108,7 +108,7 @@ | |||
315 | 108 | # See comment about domination input format and ordering above. | 108 | # See comment about domination input format and ordering above. |
316 | 109 | binary_input = {'foo-bin': [dominant, dominated]} | 109 | binary_input = {'foo-bin': [dominant, dominated]} |
317 | 110 | 110 | ||
319 | 111 | dominator._dominateBinaries(binary_input) | 111 | dominator._dominatePublications(binary_input) |
320 | 112 | flush_database_updates() | 112 | flush_database_updates() |
321 | 113 | 113 | ||
322 | 114 | # Dominant version remains correctly published. | 114 | # Dominant version remains correctly published. |
323 | @@ -129,7 +129,7 @@ | |||
324 | 129 | dominator = Dominator(self.logger, self.ubuntutest.main_archive) | 129 | dominator = Dominator(self.logger, self.ubuntutest.main_archive) |
325 | 130 | binary_input = {'foo-bin': []} | 130 | binary_input = {'foo-bin': []} |
326 | 131 | self.assertRaises( | 131 | self.assertRaises( |
328 | 132 | AssertionError, dominator._dominateBinaries, binary_input) | 132 | AssertionError, dominator._dominatePublications, binary_input) |
329 | 133 | 133 | ||
330 | 134 | def testBinaryDomination(self): | 134 | def testBinaryDomination(self): |
331 | 135 | """Test binary domination unit procedure.""" | 135 | """Test binary domination unit procedure.""" |
332 | @@ -138,7 +138,7 @@ | |||
333 | 138 | [dominant_source, dominant, dominated_source, | 138 | [dominant_source, dominant, dominated_source, |
334 | 139 | dominated] = self.createSimpleDominationContext() | 139 | dominated] = self.createSimpleDominationContext() |
335 | 140 | 140 | ||
337 | 141 | dominator._dominateBinary(dominated, dominant) | 141 | dominated.supersede(dominant) |
338 | 142 | flush_database_updates() | 142 | flush_database_updates() |
339 | 143 | 143 | ||
340 | 144 | dominated = self.checkBinaryPublication( | 144 | dominated = self.checkBinaryPublication( |
341 | @@ -150,7 +150,7 @@ | |||
342 | 150 | def testBinaryDominationAssertsPendingOrPublished(self): | 150 | def testBinaryDominationAssertsPendingOrPublished(self): |
343 | 151 | """Test binary domination asserts coherent dominated status. | 151 | """Test binary domination asserts coherent dominated status. |
344 | 152 | 152 | ||
346 | 153 | Normally _dominateBinary only accepts domination candidates in | 153 | Normally supersede() only accepts domination candidates in |
347 | 154 | PUBLISHED or PENDING status, a exception is opened for architecture | 154 | PUBLISHED or PENDING status, a exception is opened for architecture |
348 | 155 | independent binaries because during the iteration they might have | 155 | independent binaries because during the iteration they might have |
349 | 156 | been already SUPERSEDED with its first publication, when it happens | 156 | been already SUPERSEDED with its first publication, when it happens |
350 | @@ -165,7 +165,7 @@ | |||
351 | 165 | dominated] = self.createSimpleDominationContext() | 165 | dominated] = self.createSimpleDominationContext() |
352 | 166 | 166 | ||
353 | 167 | # Let's modify the domination candidate, so it will look wrong to | 167 | # Let's modify the domination candidate, so it will look wrong to |
355 | 168 | # _dominateBinary which will raise because it's a architecture | 168 | # supersede() which will raise because it's a architecture |
356 | 169 | # specific binary publication not in PENDING or PUBLISHED state. | 169 | # specific binary publication not in PENDING or PUBLISHED state. |
357 | 170 | dominated.status = PackagePublishingStatus.SUPERSEDED | 170 | dominated.status = PackagePublishingStatus.SUPERSEDED |
358 | 171 | manual_domination_date = datetime.datetime( | 171 | manual_domination_date = datetime.datetime( |
359 | @@ -176,7 +176,7 @@ | |||
360 | 176 | # An error like that in production clearly indicates that something | 176 | # An error like that in production clearly indicates that something |
361 | 177 | # is wrong in the Dominator look-up methods. | 177 | # is wrong in the Dominator look-up methods. |
362 | 178 | self.assertRaises( | 178 | self.assertRaises( |
364 | 179 | AssertionError, dominator._dominateBinary, dominated, dominant) | 179 | AssertionError, dominated.supersede, dominant) |
365 | 180 | 180 | ||
366 | 181 | # The refused publishing record remains the same. | 181 | # The refused publishing record remains the same. |
367 | 182 | dominated = self.checkBinaryPublication( | 182 | dominated = self.checkBinaryPublication( |
368 | @@ -188,7 +188,7 @@ | |||
369 | 188 | dominated.binarypackagerelease.architecturespecific = False | 188 | dominated.binarypackagerelease.architecturespecific = False |
370 | 189 | flush_database_updates() | 189 | flush_database_updates() |
371 | 190 | 190 | ||
373 | 191 | dominator._dominateBinary(dominated, dominant) | 191 | dominated.supersede(dominant) |
374 | 192 | flush_database_updates() | 192 | flush_database_updates() |
375 | 193 | dominated = self.checkBinaryPublication( | 193 | dominated = self.checkBinaryPublication( |
376 | 194 | dominated, PackagePublishingStatus.SUPERSEDED) | 194 | dominated, PackagePublishingStatus.SUPERSEDED) |
377 | @@ -197,14 +197,12 @@ | |||
378 | 197 | def testOtherBinaryPublications(self): | 197 | def testOtherBinaryPublications(self): |
379 | 198 | """Check the basis of architecture independent binary domination. | 198 | """Check the basis of architecture independent binary domination. |
380 | 199 | 199 | ||
383 | 200 | We use _getOtherBinaryPublications to identify other publications of | 200 | We use _getOtherPublications to identify other publications of the |
384 | 201 | the same binarypackagerelease in other architectures (architecture | 201 | same binarypackagerelease in other architectures (architecture |
385 | 202 | independent binaries), they will be dominated during a single step. | 202 | independent binaries), they will be dominated during a single step. |
386 | 203 | 203 | ||
387 | 204 | See overall details in `testDominationOfOldArchIndepBinaries`. | 204 | See overall details in `testDominationOfOldArchIndepBinaries`. |
388 | 205 | """ | 205 | """ |
389 | 206 | dominator = Dominator(self.logger, self.ubuntutest.main_archive) | ||
390 | 207 | |||
391 | 208 | # Create architecture independent publications for foo-bin_1.0 | 206 | # Create architecture independent publications for foo-bin_1.0 |
392 | 209 | # in i386 & hppa. | 207 | # in i386 & hppa. |
393 | 210 | pub_source_archindep = self.getPubSource( | 208 | pub_source_archindep = self.getPubSource( |
394 | @@ -232,7 +230,7 @@ | |||
395 | 232 | 230 | ||
396 | 233 | # Check if we can reach the i386 publication using | 231 | # Check if we can reach the i386 publication using |
397 | 234 | # _getOtherBinaryPublications over the hppa binary. | 232 | # _getOtherBinaryPublications over the hppa binary. |
399 | 235 | [found] = list(dominator._getOtherBinaryPublications(hppa_pub)) | 233 | [found] = list(hppa_pub._getOtherPublications()) |
400 | 236 | self.assertEqual(i386_pub, found) | 234 | self.assertEqual(i386_pub, found) |
401 | 237 | 235 | ||
402 | 238 | # Create architecture specific publications for foo-bin_1.1 in | 236 | # Create architecture specific publications for foo-bin_1.1 in |
403 | @@ -251,7 +249,7 @@ | |||
404 | 251 | # Check if there is no other publication of the hppa binary package | 249 | # Check if there is no other publication of the hppa binary package |
405 | 252 | # release. | 250 | # release. |
406 | 253 | self.assertEqual( | 251 | self.assertEqual( |
408 | 254 | dominator._getOtherBinaryPublications(hppa_pub).count(), | 252 | hppa_pub._getOtherPublications().count(), |
409 | 255 | 0) | 253 | 0) |
410 | 256 | 254 | ||
411 | 257 | def testDominationOfOldArchIndepBinaries(self): | 255 | def testDominationOfOldArchIndepBinaries(self): |
412 | 258 | 256 | ||
413 | === modified file 'lib/lp/registry/doc/distroseries.txt' | |||
414 | --- lib/lp/registry/doc/distroseries.txt 2010-06-22 19:37:43 +0000 | |||
415 | +++ lib/lp/registry/doc/distroseries.txt 2010-07-20 09:44:57 +0000 | |||
416 | @@ -593,17 +593,17 @@ | |||
417 | 593 | Supersede previous netapplet publication: | 593 | Supersede previous netapplet publication: |
418 | 594 | 594 | ||
419 | 595 | >>> last_published = netapplet_srcrel.publishing_history[1] | 595 | >>> last_published = netapplet_srcrel.publishing_history[1] |
421 | 596 | >>> superseded_netapplet = last_published.supersede() | 596 | >>> last_published.supersede() |
422 | 597 | >>> flush_database_updates() | 597 | >>> flush_database_updates() |
423 | 598 | 598 | ||
424 | 599 | >>> netapplet_srcrel.publishing_history.count() | 599 | >>> netapplet_srcrel.publishing_history.count() |
425 | 600 | 2 | 600 | 2 |
426 | 601 | 601 | ||
428 | 602 | >>> print superseded_netapplet.status.name | 602 | >>> print last_published.status.name |
429 | 603 | SUPERSEDED | 603 | SUPERSEDED |
430 | 604 | 604 | ||
431 | 605 | >>> from canonical.database.sqlbase import get_transaction_timestamp | 605 | >>> from canonical.database.sqlbase import get_transaction_timestamp |
433 | 606 | >>> superseded_netapplet.datesuperseded == get_transaction_timestamp() | 606 | >>> last_published.datesuperseded == get_transaction_timestamp() |
434 | 607 | True | 607 | True |
435 | 608 | 608 | ||
436 | 609 | 609 | ||
437 | 610 | 610 | ||
438 | === modified file 'lib/lp/soyuz/doc/archive.txt' | |||
439 | --- lib/lp/soyuz/doc/archive.txt 2010-07-02 21:25:36 +0000 | |||
440 | +++ lib/lp/soyuz/doc/archive.txt 2010-07-20 09:44:57 +0000 | |||
441 | @@ -913,10 +913,8 @@ | |||
442 | 913 | 913 | ||
443 | 914 | >>> cprov_archive.number_of_sources | 914 | >>> cprov_archive.number_of_sources |
444 | 915 | 3 | 915 | 3 |
446 | 916 | >>> superseded = cprov_archive.getPublishedSources( | 916 | >>> cprov_archive.getPublishedSources( |
447 | 917 | ... name='cdrkit')[0].supersede() | 917 | ... name='cdrkit')[0].supersede() |
448 | 918 | >>> from canonical.launchpad.ftests import syncUpdate | ||
449 | 919 | >>> syncUpdate(superseded) | ||
450 | 920 | 918 | ||
451 | 921 | >>> cprov_archive.number_of_sources | 919 | >>> cprov_archive.number_of_sources |
452 | 922 | 2 | 920 | 2 |
453 | @@ -926,9 +924,8 @@ | |||
454 | 926 | 924 | ||
455 | 927 | >>> cprov_archive.number_of_binaries | 925 | >>> cprov_archive.number_of_binaries |
456 | 928 | 3 | 926 | 3 |
458 | 929 | >>> superseded = cprov_archive.getAllPublishedBinaries( | 927 | >>> cprov_archive.getAllPublishedBinaries( |
459 | 930 | ... name='mozilla-firefox')[0].supersede() | 928 | ... name='mozilla-firefox')[0].supersede() |
460 | 931 | >>> syncUpdate(superseded) | ||
461 | 932 | 929 | ||
462 | 933 | >>> cprov_archive.number_of_binaries | 930 | >>> cprov_archive.number_of_binaries |
463 | 934 | 2 | 931 | 2 |
464 | @@ -982,7 +979,6 @@ | |||
465 | 982 | 979 | ||
466 | 983 | >>> login("celso.providelo@canonical.com") | 980 | >>> login("celso.providelo@canonical.com") |
467 | 984 | >>> removal_candidate.requestDeletion(cprov, 'go away !') | 981 | >>> removal_candidate.requestDeletion(cprov, 'go away !') |
468 | 985 | >>> syncUpdate(removal_candidate) | ||
469 | 986 | 982 | ||
470 | 987 | >>> cprov_archive.getSourcesForDeletion(name='ice').count() | 983 | >>> cprov_archive.getSourcesForDeletion(name='ice').count() |
471 | 988 | 1 | 984 | 1 |
472 | @@ -1022,7 +1018,6 @@ | |||
473 | 1022 | 1018 | ||
474 | 1023 | >>> for bin in removal_candidate.getPublishedBinaries(): | 1019 | >>> for bin in removal_candidate.getPublishedBinaries(): |
475 | 1024 | ... bin.requestDeletion(cprov, 'go away !') | 1020 | ... bin.requestDeletion(cprov, 'go away !') |
476 | 1025 | ... syncUpdate(bin) | ||
477 | 1026 | 1021 | ||
478 | 1027 | >>> cprov_archive.getSourcesForDeletion(name='ice').count() | 1022 | >>> cprov_archive.getSourcesForDeletion(name='ice').count() |
479 | 1028 | 0 | 1023 | 0 |
480 | 1029 | 1024 | ||
481 | === modified file 'lib/lp/soyuz/doc/distroarchseries.txt' | |||
482 | --- lib/lp/soyuz/doc/distroarchseries.txt 2010-05-13 20:01:58 +0000 | |||
483 | +++ lib/lp/soyuz/doc/distroarchseries.txt 2010-07-20 09:44:57 +0000 | |||
484 | @@ -123,12 +123,11 @@ | |||
485 | 123 | 123 | ||
486 | 124 | Supersede current publication: | 124 | Supersede current publication: |
487 | 125 | 125 | ||
490 | 126 | >>> pmount_pubrec = pmount_hoary_i386_released.current_publishing_record | 126 | >>> pub = pmount_hoary_i386_released.current_publishing_record |
491 | 127 | >>> superseded_pmount = pmount_pubrec.supersede() | 127 | >>> pub.supersede() |
492 | 128 | >>> pmount_hoary_i386.publishing_history.count() | 128 | >>> pmount_hoary_i386.publishing_history.count() |
493 | 129 | 3 | 129 | 3 |
494 | 130 | 130 | ||
495 | 131 | >>> pub = superseded_pmount | ||
496 | 132 | >>> print pub.status.name, pub.datesuperseded is not None | 131 | >>> print pub.status.name, pub.datesuperseded is not None |
497 | 133 | SUPERSEDED True | 132 | SUPERSEDED True |
498 | 134 | 133 | ||
499 | 135 | 134 | ||
500 | === modified file 'lib/lp/soyuz/doc/publishing.txt' | |||
501 | --- lib/lp/soyuz/doc/publishing.txt 2010-05-27 22:18:16 +0000 | |||
502 | +++ lib/lp/soyuz/doc/publishing.txt 2010-07-20 09:44:57 +0000 | |||
503 | @@ -543,11 +543,8 @@ | |||
504 | 543 | excluded from the getPublishedBinaries() results, but not from the | 543 | excluded from the getPublishedBinaries() results, but not from the |
505 | 544 | getBuiltBinaries() result. | 544 | getBuiltBinaries() result. |
506 | 545 | 545 | ||
507 | 546 | >>> from canonical.launchpad.ftests import syncUpdate | ||
508 | 547 | |||
509 | 548 | >>> a_binary = source.getPublishedBinaries()[0] | 546 | >>> a_binary = source.getPublishedBinaries()[0] |
512 | 549 | >>> superseded = a_binary.supersede() | 547 | >>> a_binary.supersede() |
511 | 550 | >>> syncUpdate(superseded) | ||
513 | 551 | 548 | ||
514 | 552 | >>> len(source.getPublishedBinaries()) | 549 | >>> len(source.getPublishedBinaries()) |
515 | 553 | 1 | 550 | 1 |
516 | @@ -561,7 +558,6 @@ | |||
517 | 561 | >>> deletable = source.getPublishedBinaries()[0] | 558 | >>> deletable = source.getPublishedBinaries()[0] |
518 | 562 | >>> deletable.requestDeletion(mark, "go") | 559 | >>> deletable.requestDeletion(mark, "go") |
519 | 563 | >>> deleted = deletable | 560 | >>> deleted = deletable |
520 | 564 | >>> syncUpdate(deleted) | ||
521 | 565 | 561 | ||
522 | 566 | >>> len(source.getPublishedBinaries()) | 562 | >>> len(source.getPublishedBinaries()) |
523 | 567 | 0 | 563 | 0 |
524 | @@ -577,7 +573,6 @@ | |||
525 | 577 | 573 | ||
526 | 578 | >>> for bin in copied_source.getPublishedBinaries(): | 574 | >>> for bin in copied_source.getPublishedBinaries(): |
527 | 579 | ... obsoleted = bin.requestObsolescence() | 575 | ... obsoleted = bin.requestObsolescence() |
528 | 580 | ... syncUpdate(obsoleted) | ||
529 | 581 | 576 | ||
530 | 582 | >>> len(copied_source.getPublishedBinaries()) | 577 | >>> len(copied_source.getPublishedBinaries()) |
531 | 583 | 0 | 578 | 0 |
532 | @@ -596,7 +591,6 @@ | |||
533 | 596 | >>> for pub in copied_source.getBuiltBinaries(): | 591 | >>> for pub in copied_source.getBuiltBinaries(): |
534 | 597 | ... pub.status = PackagePublishingStatus.PUBLISHED | 592 | ... pub.status = PackagePublishingStatus.PUBLISHED |
535 | 598 | ... pub.scheduleddeletiondate = None | 593 | ... pub.scheduleddeletiondate = None |
536 | 599 | ... syncUpdate(pub) | ||
537 | 600 | 594 | ||
538 | 601 | Now we override the first binary publication, the hppa one, to | 595 | Now we override the first binary publication, the hppa one, to |
539 | 602 | component 'universe'. | 596 | component 'universe'. |
540 | @@ -631,10 +625,8 @@ | |||
541 | 631 | We have to re-publish the superseded and the deleted publications above | 625 | We have to re-publish the superseded and the deleted publications above |
542 | 632 | because it's used below. | 626 | because it's used below. |
543 | 633 | 627 | ||
546 | 634 | >>> superseded.status = PackagePublishingStatus.PUBLISHED | 628 | >>> a_binary.status = PackagePublishingStatus.PUBLISHED |
545 | 635 | >>> syncUpdate(superseded) | ||
547 | 636 | >>> deleted.status = PackagePublishingStatus.PUBLISHED | 629 | >>> deleted.status = PackagePublishingStatus.PUBLISHED |
548 | 637 | >>> syncUpdate(deleted) | ||
549 | 638 | 630 | ||
550 | 639 | 631 | ||
551 | 640 | Copying and inspecting architecture independent binaries | 632 | Copying and inspecting architecture independent binaries |
552 | 641 | 633 | ||
553 | === modified file 'lib/lp/soyuz/interfaces/publishing.py' | |||
554 | --- lib/lp/soyuz/interfaces/publishing.py 2010-03-11 02:32:07 +0000 | |||
555 | +++ lib/lp/soyuz/interfaces/publishing.py 2010-07-20 09:44:57 +0000 | |||
556 | @@ -278,12 +278,7 @@ | |||
557 | 278 | """ | 278 | """ |
558 | 279 | 279 | ||
559 | 280 | def supersede(): | 280 | def supersede(): |
566 | 281 | """Supersede this publication. | 281 | """Supersede this publication.""" |
561 | 282 | |||
562 | 283 | :return: The superseded publishing records, either a | ||
563 | 284 | `ISourcePackagePublishingHistory` or | ||
564 | 285 | `IBinaryPackagePublishingHistory`. | ||
565 | 286 | """ | ||
567 | 287 | 282 | ||
568 | 288 | def requestObsolescence(): | 283 | def requestObsolescence(): |
569 | 289 | """Make this publication obsolete. | 284 | """Make this publication obsolete. |
570 | @@ -632,6 +627,15 @@ | |||
571 | 632 | :return: a list of `ILibraryFileAlias`. | 627 | :return: a list of `ILibraryFileAlias`. |
572 | 633 | """ | 628 | """ |
573 | 634 | 629 | ||
574 | 630 | def supersede(dominant=None, logger=None): | ||
575 | 631 | """Supersede this publication. | ||
576 | 632 | |||
577 | 633 | :param dominant: optional `ISourcePackagePublishingHistory` which is | ||
578 | 634 | triggering the domination. | ||
579 | 635 | :param logger: optional object to which debug information will be | ||
580 | 636 | logged. | ||
581 | 637 | """ | ||
582 | 638 | |||
583 | 635 | def changeOverride(new_component=None, new_section=None): | 639 | def changeOverride(new_component=None, new_section=None): |
584 | 636 | """Change the component and/or section of this publication | 640 | """Change the component and/or section of this publication |
585 | 637 | 641 | ||
586 | @@ -838,6 +842,15 @@ | |||
587 | 838 | title=_("Priority Name"), | 842 | title=_("Priority Name"), |
588 | 839 | required=False, readonly=True)) | 843 | required=False, readonly=True)) |
589 | 840 | 844 | ||
590 | 845 | def supersede(dominant=None, logger=None): | ||
591 | 846 | """Supersede this publication. | ||
592 | 847 | |||
593 | 848 | :param dominant: optional `IBinaryPackagePublishingHistory` which is | ||
594 | 849 | triggering the domination. | ||
595 | 850 | :param logger: optional object to which debug information will be | ||
596 | 851 | logged. | ||
597 | 852 | """ | ||
598 | 853 | |||
599 | 841 | def changeOverride(new_component=None, new_section=None, | 854 | def changeOverride(new_component=None, new_section=None, |
600 | 842 | new_priority=None): | 855 | new_priority=None): |
601 | 843 | """Change the component, section and/or priority of this publication. | 856 | """Change the component, section and/or priority of this publication. |
602 | 844 | 857 | ||
603 | === modified file 'lib/lp/soyuz/model/publishing.py' | |||
604 | --- lib/lp/soyuz/model/publishing.py 2010-07-20 09:16:14 +0000 | |||
605 | +++ lib/lp/soyuz/model/publishing.py 2010-07-20 09:44:57 +0000 | |||
606 | @@ -37,6 +37,7 @@ | |||
607 | 37 | from canonical.database.enumcol import EnumCol | 37 | from canonical.database.enumcol import EnumCol |
608 | 38 | from canonical.launchpad.components.decoratedresultset import ( | 38 | from canonical.launchpad.components.decoratedresultset import ( |
609 | 39 | DecoratedResultSet) | 39 | DecoratedResultSet) |
610 | 40 | from canonical.launchpad.interfaces.lpstorm import IMasterStore | ||
611 | 40 | from canonical.launchpad.webapp.interfaces import ( | 41 | from canonical.launchpad.webapp.interfaces import ( |
612 | 41 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) | 42 | IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR) |
613 | 42 | from canonical.launchpad.webapp.interfaces import NotFoundError | 43 | from canonical.launchpad.webapp.interfaces import NotFoundError |
614 | @@ -70,6 +71,10 @@ | |||
615 | 70 | from lp.soyuz.scripts.changeoverride import ArchiveOverriderError | 71 | from lp.soyuz.scripts.changeoverride import ArchiveOverriderError |
616 | 71 | 72 | ||
617 | 72 | 73 | ||
618 | 74 | PENDING = PackagePublishingStatus.PENDING | ||
619 | 75 | PUBLISHED = PackagePublishingStatus.PUBLISHED | ||
620 | 76 | |||
621 | 77 | |||
622 | 73 | # XXX cprov 2006-08-18: move it away, perhaps archivepublisher/pool.py | 78 | # XXX cprov 2006-08-18: move it away, perhaps archivepublisher/pool.py |
623 | 74 | def makePoolPath(source_name, component_name): | 79 | def makePoolPath(source_name, component_name): |
624 | 75 | """Return the pool path for a given source name and component name.""" | 80 | """Return the pool path for a given source name and component name.""" |
625 | @@ -271,7 +276,6 @@ | |||
626 | 271 | """See `IPublishing`.""" | 276 | """See `IPublishing`.""" |
627 | 272 | self.status = PackagePublishingStatus.SUPERSEDED | 277 | self.status = PackagePublishingStatus.SUPERSEDED |
628 | 273 | self.datesuperseded = UTC_NOW | 278 | self.datesuperseded = UTC_NOW |
629 | 274 | return self | ||
630 | 275 | 279 | ||
631 | 276 | def requestDeletion(self, removed_by, removal_comment=None): | 280 | def requestDeletion(self, removed_by, removal_comment=None): |
632 | 277 | """See `IPublishing`.""" | 281 | """See `IPublishing`.""" |
633 | @@ -673,6 +677,25 @@ | |||
634 | 673 | 677 | ||
635 | 674 | return fields | 678 | return fields |
636 | 675 | 679 | ||
637 | 680 | def supersede(self, dominant=None, logger=None): | ||
638 | 681 | """See `ISourcePackagePublishingHistory`.""" | ||
639 | 682 | assert self.status in [PUBLISHED, PENDING], ( | ||
640 | 683 | "Should not dominate unpublished source %s" % | ||
641 | 684 | self.sourcepackagerelease.title) | ||
642 | 685 | |||
643 | 686 | super(SourcePackagePublishingHistory, self).supersede() | ||
644 | 687 | |||
645 | 688 | if dominant is not None: | ||
646 | 689 | if logger is not None: | ||
647 | 690 | logger.debug( | ||
648 | 691 | "%s/%s has been judged as superseded by %s/%s" % | ||
649 | 692 | (self.sourcepackagerelease.sourcepackagename.name, | ||
650 | 693 | self.sourcepackagerelease.version, | ||
651 | 694 | dominant.sourcepackagerelease.sourcepackagename.name, | ||
652 | 695 | dominant.sourcepackagerelease.version)) | ||
653 | 696 | |||
654 | 697 | self.supersededby = dominant.sourcepackagerelease | ||
655 | 698 | |||
656 | 676 | def changeOverride(self, new_component=None, new_section=None): | 699 | def changeOverride(self, new_component=None, new_section=None): |
657 | 677 | """See `ISourcePackagePublishingHistory`.""" | 700 | """See `ISourcePackagePublishingHistory`.""" |
658 | 678 | # Check we have been asked to do something | 701 | # Check we have been asked to do something |
659 | @@ -927,6 +950,73 @@ | |||
660 | 927 | 950 | ||
661 | 928 | return fields | 951 | return fields |
662 | 929 | 952 | ||
663 | 953 | def _getOtherPublications(self): | ||
664 | 954 | """Return remaining publications with the same overrides. | ||
665 | 955 | |||
666 | 956 | Only considers binary publications in the same archive, distroseries, | ||
667 | 957 | pocket, component, section and priority context. These publications | ||
668 | 958 | are candidates for domination if this is an architecture-independent | ||
669 | 959 | package. | ||
670 | 960 | |||
671 | 961 | The override match is critical -- it prevents a publication created | ||
672 | 962 | by new overrides from superseding itself. | ||
673 | 963 | """ | ||
674 | 964 | available_architectures = [ | ||
675 | 965 | das.id for das in self.distroarchseries.distroseries.architectures] | ||
676 | 966 | return IMasterStore(BinaryPackagePublishingHistory).find( | ||
677 | 967 | BinaryPackagePublishingHistory, | ||
678 | 968 | BinaryPackagePublishingHistory.status.is_in( | ||
679 | 969 | [PUBLISHED, PENDING]), | ||
680 | 970 | BinaryPackagePublishingHistory.distroarchseries in ( | ||
681 | 971 | available_architectures), | ||
682 | 972 | binarypackagerelease=self.binarypackagerelease, | ||
683 | 973 | archive=self.archive, | ||
684 | 974 | pocket=self.pocket, | ||
685 | 975 | component=self.component, | ||
686 | 976 | section=self.section, | ||
687 | 977 | priority=self.priority) | ||
688 | 978 | |||
689 | 979 | def supersede(self, dominant=None, logger=None): | ||
690 | 980 | """See `IBinaryPackagePublishingHistory`.""" | ||
691 | 981 | # At this point only PUBLISHED (ancient versions) or PENDING ( | ||
692 | 982 | # multiple overrides/copies) publications should be given. We | ||
693 | 983 | # tolerate SUPERSEDED architecture-independent binaries, because | ||
694 | 984 | # they are dominated automatically once the first publication is | ||
695 | 985 | # processed. | ||
696 | 986 | if self.status not in [PUBLISHED, PENDING]: | ||
697 | 987 | assert not self.binarypackagerelease.architecturespecific, ( | ||
698 | 988 | "Should not dominate unpublished architecture specific " | ||
699 | 989 | "binary %s (%s)" % ( | ||
700 | 990 | self.binarypackagerelease.title, | ||
701 | 991 | self.distroarchseries.architecturetag)) | ||
702 | 992 | return | ||
703 | 993 | |||
704 | 994 | super(BinaryPackagePublishingHistory, self).supersede() | ||
705 | 995 | |||
706 | 996 | if dominant is not None: | ||
707 | 997 | dominant_build = dominant.binarypackagerelease.build | ||
708 | 998 | distroarchseries = dominant_build.distro_arch_series | ||
709 | 999 | if logger is not None: | ||
710 | 1000 | logger.debug( | ||
711 | 1001 | "The %s build of %s has been judged as superseded by the " | ||
712 | 1002 | "build of %s. Arch-specific == %s" % ( | ||
713 | 1003 | distroarchseries.architecturetag, | ||
714 | 1004 | self.binarypackagerelease.title, | ||
715 | 1005 | dominant_build.source_package_release.title, | ||
716 | 1006 | self.binarypackagerelease.architecturespecific)) | ||
717 | 1007 | # Binary package releases are superseded by the new build, | ||
718 | 1008 | # not the new binary package release. This is because | ||
719 | 1009 | # there may not *be* a new matching binary package - | ||
720 | 1010 | # source packages can change the binaries they build | ||
721 | 1011 | # between releases. | ||
722 | 1012 | self.supersededby = dominant_build | ||
723 | 1013 | |||
724 | 1014 | # If this is architecture-independet, all publications with the same | ||
725 | 1015 | # context and overrides should be dominated simultaneously. | ||
726 | 1016 | if not self.binarypackagerelease.architecturespecific: | ||
727 | 1017 | for dominated in self._getOtherPublications(): | ||
728 | 1018 | dominated.supersede(dominant, logger) | ||
729 | 1019 | |||
730 | 930 | def changeOverride(self, new_component=None, new_section=None, | 1020 | def changeOverride(self, new_component=None, new_section=None, |
731 | 931 | new_priority=None): | 1021 | new_priority=None): |
732 | 932 | """See `IBinaryPackagePublishingHistory`.""" | 1022 | """See `IBinaryPackagePublishingHistory`.""" |
733 | 933 | 1023 | ||
734 | === modified file 'lib/lp/soyuz/scripts/ftpmaster.py' | |||
735 | --- lib/lp/soyuz/scripts/ftpmaster.py 2010-04-13 14:28:58 +0000 | |||
736 | +++ lib/lp/soyuz/scripts/ftpmaster.py 2010-07-20 09:44:57 +0000 | |||
737 | @@ -451,13 +451,14 @@ | |||
738 | 451 | dasbp = distroarchseries.getBinaryPackage(binarypackagename) | 451 | dasbp = distroarchseries.getBinaryPackage(binarypackagename) |
739 | 452 | dasbpr = dasbp.currentrelease | 452 | dasbpr = dasbp.currentrelease |
740 | 453 | try: | 453 | try: |
742 | 454 | sbpph = dasbpr.current_publishing_record.supersede() | 454 | bpph = dasbpr.current_publishing_record |
743 | 455 | bpph.supersede() | ||
744 | 455 | # We're blindly removing for all arches, if it's not there | 456 | # We're blindly removing for all arches, if it's not there |
745 | 456 | # for some, that's fine ... | 457 | # for some, that's fine ... |
746 | 457 | except NotFoundError: | 458 | except NotFoundError: |
747 | 458 | pass | 459 | pass |
748 | 459 | else: | 460 | else: |
750 | 460 | version = sbpph.binarypackagerelease.version | 461 | version = bpph.binarypackagerelease.version |
751 | 461 | self.logger.info ("Removed %s_%s from %s/%s ... " | 462 | self.logger.info ("Removed %s_%s from %s/%s ... " |
752 | 462 | % (package, version, | 463 | % (package, version, |
753 | 463 | self.distroseries.name, | 464 | self.distroseries.name, |
your VWS in supersede doesn't really gel for me - please remove or comment