1
# Copyright 2011 Canonical Ltd. This software is licensed under the
2
# GNU Affero General Public License version 3 (see the file LICENSE).
4
"""Generic Override Policy classes.
10
'FromExistingOverridePolicy',
11
'UbuntuOverridePolicy',
12
'UnknownOverridePolicy',
16
from storm.expr import (
23
from canonical.launchpad.components.decoratedresultset import (
26
from canonical.launchpad.interfaces.lpstorm import IStore
27
from lp.registry.model.sourcepackagename import SourcePackageName
28
from lp.services.database import bulk
29
from lp.soyuz.interfaces.publishing import active_publishing_status
30
from lp.soyuz.model.binarypackagename import BinaryPackageName
31
from lp.soyuz.model.binarypackagerelease import BinaryPackageRelease
32
from lp.soyuz.model.component import Component
33
from lp.soyuz.model.distroarchseries import DistroArchSeries
34
from lp.soyuz.model.publishing import (
35
BinaryPackagePublishingHistory,
36
SourcePackagePublishingHistory,
38
from lp.soyuz.model.section import Section
39
from lp.soyuz.model.sourcepackagerelease import SourcePackageRelease
42
class BaseOverridePolicy:
44
def calculateSourceOverrides(self, archive, distroseries, pocket,
46
raise NotImplementedError()
48
def calculateBinaryOverrides(self, archive, distroseries, pocket,
50
raise NotImplementedError()
53
class FromExistingOverridePolicy(BaseOverridePolicy):
54
"""Override policy that only searches for existing publications.
56
Override policy that returns the SourcePackageName, component and
57
section for the latest published source publication, or the
58
BinaryPackageName, DistroArchSeries, component, section and priority
59
for the latest published binary publication.
62
def calculateSourceOverrides(self, archive, distroseries, pocket, spns):
63
store = IStore(SourcePackagePublishingHistory)
65
bulk.load(Component, (row[1] for row in rows))
66
bulk.load(Section, (row[2] for row in rows))
67
already_published = DecoratedResultSet(
69
(SourcePackageRelease.sourcepackagenameID,
70
SourcePackagePublishingHistory.componentID,
71
SourcePackagePublishingHistory.sectionID),
72
SourcePackagePublishingHistory.pocket == pocket,
73
SourcePackagePublishingHistory.archiveID == archive.id,
74
SourcePackagePublishingHistory.distroseriesID ==
76
SourcePackagePublishingHistory.status.is_in(
77
active_publishing_status),
78
SourcePackageRelease.id ==
79
SourcePackagePublishingHistory.sourcepackagereleaseID,
80
SourcePackageRelease.sourcepackagenameID.is_in(
81
spn.id for spn in spns)).order_by(
82
SourcePackageRelease.sourcepackagenameID,
83
Desc(SourcePackagePublishingHistory.datecreated),
84
Desc(SourcePackagePublishingHistory.id),
86
distinct=(SourcePackageRelease.sourcepackagenameID,)),
87
id_resolver((SourcePackageName, Component, Section)),
88
pre_iter_hook=eager_load)
89
return list(already_published)
91
def calculateBinaryOverrides(self, archive, distroseries, pocket,
93
store = IStore(BinaryPackagePublishingHistory)
95
bulk.load(Component, (row[2] for row in rows))
96
bulk.load(Section, (row[3] for row in rows))
97
expanded = calculate_target_das(distroseries, binaries)
99
make_package_condition(archive, das, bpn)
100
for bpn, das in expanded)
101
already_published = DecoratedResultSet(
103
(BinaryPackageRelease.binarypackagenameID,
104
BinaryPackagePublishingHistory.distroarchseriesID,
105
BinaryPackagePublishingHistory.componentID,
106
BinaryPackagePublishingHistory.sectionID,
107
BinaryPackagePublishingHistory.priority),
108
BinaryPackagePublishingHistory.pocket == pocket,
109
BinaryPackagePublishingHistory.status.is_in(
110
active_publishing_status),
111
BinaryPackageRelease.id ==
112
BinaryPackagePublishingHistory.binarypackagereleaseID,
113
Or(*candidates)).order_by(
114
BinaryPackagePublishingHistory.distroarchseriesID,
115
BinaryPackageRelease.binarypackagenameID,
116
Desc(BinaryPackagePublishingHistory.datecreated),
117
Desc(BinaryPackagePublishingHistory.id),
119
BinaryPackagePublishingHistory.distroarchseriesID,
120
BinaryPackageRelease.binarypackagenameID,
124
(BinaryPackageName, DistroArchSeries, Component, Section,
126
pre_iter_hook=eager_load)
127
return list(already_published)
130
class UnknownOverridePolicy(BaseOverridePolicy):
131
"""Override policy that returns defaults.
133
Override policy that assumes everything passed in doesn't exist, so
134
returns the defaults.
137
def calculateSourceOverrides(self, archive, distroseries, pocket,
139
default_component = archive.default_component or 'universe'
140
return [(source, default_component, None) for source in sources]
142
def calculateBinaryOverrides(self, archive, distroseries, pocket,
144
default_component = archive.default_component or 'universe'
146
(binary, das, default_component, None, None)
147
for binary, das in calculate_target_das(distroseries, binaries)]
150
class UbuntuOverridePolicy(FromExistingOverridePolicy,
151
UnknownOverridePolicy):
152
"""Override policy for Ubuntu.
154
An override policy that incorporates both the from existing policy
155
and the unknown policy.
158
def calculateSourceOverrides(self, archive, distroseries, pocket,
161
overrides = FromExistingOverridePolicy.calculateSourceOverrides(
162
self, archive, distroseries, pocket, sources)
163
existing = set(override[0] for override in overrides)
164
missing = total.difference(existing)
166
unknown = UnknownOverridePolicy.calculateSourceOverrides(
167
self, archive, distroseries, pocket, missing)
168
overrides.extend(unknown)
171
def calculateBinaryOverrides(self, archive, distroseries, pocket,
173
total = set(binaries)
174
overrides = FromExistingOverridePolicy.calculateBinaryOverrides(
175
self, archive, distroseries, pocket, binaries)
177
overide[0], overide[1].architecturetag)
178
for overide in overrides)
179
missing = total.difference(existing)
181
unknown = UnknownOverridePolicy.calculateBinaryOverrides(
182
self, archive, distroseries, pocket, missing)
183
overrides.extend(unknown)
187
def calculate_target_das(distroseries, binaries):
189
(arch.architecturetag, arch)
190
for arch in distroseries.enabled_architectures)
193
for bpn, archtag in binaries:
194
if archtag is not None:
195
with_das.append((bpn, arch_map.get(archtag)))
197
with_das.append((bpn, distroseries.nominatedarchindep))
201
def make_package_condition(archive, das, bpn):
203
BinaryPackagePublishingHistory.archiveID == archive.id,
204
BinaryPackagePublishingHistory.distroarchseriesID == das.id,
205
BinaryPackageRelease.binarypackagenameID == bpn.id)
208
def id_resolver(lookups):
210
store = IStore(SourcePackagePublishingHistory)
212
(value if cls is None else store.get(cls, value))
213
for value, cls in zip(row, lookups))