Merge ~cjwatson/launchpad:stormify-distributionmirror into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 7397f70b394d4893985b0a7a8933f339c215fd06
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:stormify-distributionmirror
Merge into: launchpad:master
Diff against target: 483 lines (+163/-131)
4 files modified
lib/lp/registry/browser/tests/distributionmirror-views.txt (+10/-9)
lib/lp/registry/doc/distribution-mirror.txt (+2/-2)
lib/lp/registry/model/distribution.py (+16/-17)
lib/lp/registry/model/distributionmirror.py (+135/-103)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+423516@code.launchpad.net

Commit message

Convert DistributionMirror and friends to Storm

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/registry/browser/tests/distributionmirror-views.txt b/lib/lp/registry/browser/tests/distributionmirror-views.txt
2index 987809d..405de66 100644
3--- a/lib/lp/registry/browser/tests/distributionmirror-views.txt
4+++ b/lib/lp/registry/browser/tests/distributionmirror-views.txt
5@@ -372,8 +372,18 @@ A mirror that have been probed cannot be deleted.
6 ... print(notification.message)
7 This mirror has been probed and thus can't be deleted.
8
9+Only users with launchpad.Admin can access the view.
10+
11+ >>> check_permission('launchpad.Admin', view)
12+ True
13+
14+ >>> login('no-priv@canonical.com')
15+ >>> check_permission('launchpad.Admin', view)
16+ False
17+
18 Deletion is permanent.
19
20+ >>> login('karl@canonical.com')
21 >>> form = {
22 ... 'field.actions.delete': 'Delete Mirror',
23 ... }
24@@ -387,15 +397,6 @@ Deletion is permanent.
25 >>> print(ubuntu.getMirrorByName('secret.me-archive'))
26 None
27
28-Only users with launchpad.Admin can access the view.
29-
30- >>> check_permission('launchpad.Admin', view)
31- True
32-
33- >>> login('no-priv@canonical.com')
34- >>> check_permission('launchpad.Admin', view)
35- False
36-
37
38 Viewing a mirror
39 ----------------
40diff --git a/lib/lp/registry/doc/distribution-mirror.txt b/lib/lp/registry/doc/distribution-mirror.txt
41index 13fc5cf..ac05336 100644
42--- a/lib/lp/registry/doc/distribution-mirror.txt
43+++ b/lib/lp/registry/doc/distribution-mirror.txt
44@@ -981,8 +981,8 @@ for the status, however, they may not change it:
45 Traceback (most recent call last):
46 ...
47 zope.security.interfaces.Unauthorized:
48- (<DistributionMirror at ...>, 'transitionToCountryMirror',
49- 'launchpad.Admin')
50+ (<lp.registry.model.distributionmirror.DistributionMirror object at ...>,
51+ 'transitionToCountryMirror', 'launchpad.Admin')
52
53 Mirror listing administrators may change the status however:
54
55diff --git a/lib/lp/registry/model/distribution.py b/lib/lp/registry/model/distribution.py
56index 97e51c0..0581e37 100644
57--- a/lib/lp/registry/model/distribution.py
58+++ b/lib/lp/registry/model/distribution.py
59@@ -736,29 +736,29 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
60 # Since country data is needed, fetch countries into the cache.
61 list(Store.of(self).find(
62 Country,
63- Country.id.is_in(mirror.countryID for mirror in mirrors)))
64+ Country.id.is_in(mirror.country_id for mirror in mirrors)))
65
66 if needs_fresh and mirrors:
67 # Preload the distribution_mirrors' cache for mirror freshness.
68 mirror_ids = [mirror.id for mirror in mirrors]
69
70 arch_mirrors = list(Store.of(self).find(
71- (MirrorDistroArchSeries.distribution_mirrorID,
72+ (MirrorDistroArchSeries.distribution_mirror_id,
73 Max(MirrorDistroArchSeries.freshness)),
74- MirrorDistroArchSeries.distribution_mirrorID.is_in(
75+ MirrorDistroArchSeries.distribution_mirror_id.is_in(
76 mirror_ids)).group_by(
77- MirrorDistroArchSeries.distribution_mirrorID))
78+ MirrorDistroArchSeries.distribution_mirror_id))
79 arch_mirror_freshness = {}
80 arch_mirror_freshness.update(
81 [(mirror_id, MirrorFreshness.items[mirror_freshness]) for
82 (mirror_id, mirror_freshness) in arch_mirrors])
83
84 source_mirrors = list(Store.of(self).find(
85- (MirrorDistroSeriesSource.distribution_mirrorID,
86+ (MirrorDistroSeriesSource.distribution_mirror_id,
87 Max(MirrorDistroSeriesSource.freshness)),
88- MirrorDistroSeriesSource.distribution_mirrorID.is_in(
89+ MirrorDistroSeriesSource.distribution_mirror_id.is_in(
90 [mirror.id for mirror in mirrors])).group_by(
91- MirrorDistroSeriesSource.distribution_mirrorID))
92+ MirrorDistroSeriesSource.distribution_mirror_id))
93 source_mirror_freshness = {}
94 source_mirror_freshness.update(
95 [(mirror_id, MirrorFreshness.items[mirror_freshness]) for
96@@ -773,10 +773,10 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
97
98 if needs_cdimage_series and mirrors:
99 all_cdimage_series = load_referencing(
100- MirrorCDImageDistroSeries, mirrors, ["distribution_mirrorID"])
101+ MirrorCDImageDistroSeries, mirrors, ["distribution_mirror_id"])
102 cdimage_series = defaultdict(list)
103 for series in all_cdimage_series:
104- cdimage_series[series.distribution_mirrorID].append(series)
105+ cdimage_series[series.distribution_mirror_id].append(series)
106 for mirror in mirrors:
107 cache = get_property_cache(mirror)
108 cache.cdimage_series = cdimage_series.get(mirror.id, [])
109@@ -997,17 +997,14 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
110 """See `IDistribution`."""
111 # As per mvo's request we only return mirrors which have an
112 # http_base_url.
113- country_id = None
114- if country is not None:
115- country_id = country.id
116 base_query = And(
117 DistributionMirror.distribution == self,
118 DistributionMirror.content == mirror_type,
119- DistributionMirror.enabled == True,
120+ DistributionMirror.enabled,
121 DistributionMirror.http_base_url != None,
122 DistributionMirror.official_candidate == True,
123 DistributionMirror.status == MirrorStatus.OFFICIAL)
124- query = And(DistributionMirror.countryID == country_id, base_query)
125+ query = And(DistributionMirror.country == country, base_query)
126 # The list of mirrors returned by this method is fed to apt through
127 # launchpad.net, so we order the results randomly in a lame attempt to
128 # balance the load on the mirrors.
129@@ -1020,8 +1017,8 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
130 if not mirrors and country is not None:
131 continent = country.continent
132 query = And(
133- Country.q.continentID == continent.id,
134- DistributionMirror.countryID == Country.q.id,
135+ Country.continentID == continent.id,
136+ DistributionMirror.country == Country.id,
137 base_query)
138 mirrors.extend(shortlist(
139 IStore(DistributionMirror).find(
140@@ -1075,7 +1072,7 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
141 count += 1
142 name = '%s%s' % (orig_name, count)
143
144- return DistributionMirror(
145+ mirror = DistributionMirror(
146 distribution=self, owner=owner, name=name, speed=speed,
147 country=country, content=content, display_name=display_name,
148 description=description, http_base_url=urls['http_base_url'],
149@@ -1084,6 +1081,8 @@ class Distribution(SQLBase, BugTargetBase, MakesAnnouncements,
150 rsync_base_url=urls['rsync_base_url'],
151 official_candidate=official_candidate, enabled=enabled,
152 whiteboard=whiteboard)
153+ IStore(DistributionMirror).add(mirror)
154+ return mirror
155
156 @property
157 def currentseries(self):
158diff --git a/lib/lp/registry/model/distributionmirror.py b/lib/lp/registry/model/distributionmirror.py
159index eb6ed3c..96e6885 100644
160--- a/lib/lp/registry/model/distributionmirror.py
161+++ b/lib/lp/registry/model/distributionmirror.py
162@@ -26,11 +26,16 @@ from storm.expr import (
163 )
164 from storm.locals import (
165 And,
166+ Bool,
167+ DateTime,
168 Desc,
169+ Int,
170 Max,
171 Or,
172+ Reference,
173 Select,
174 Store,
175+ Unicode,
176 )
177 from storm.store import EmptyResultSet
178 from zope.interface import implementer
179@@ -67,15 +72,9 @@ from lp.registry.interfaces.series import SeriesStatus
180 from lp.registry.interfaces.sourcepackage import SourcePackageFileType
181 from lp.services.config import config
182 from lp.services.database.constants import UTC_NOW
183-from lp.services.database.datetimecol import UtcDateTimeCol
184 from lp.services.database.enumcol import DBEnum
185 from lp.services.database.interfaces import IStore
186-from lp.services.database.sqlbase import SQLBase
187-from lp.services.database.sqlobject import (
188- BoolCol,
189- ForeignKey,
190- StringCol,
191- )
192+from lp.services.database.stormbase import StormBase
193 from lp.services.mail.helpers import (
194 get_contact_email_addresses,
195 get_email_template,
196@@ -108,52 +107,60 @@ from lp.soyuz.model.publishing import (
197
198
199 @implementer(IDistributionMirror)
200-class DistributionMirror(SQLBase):
201+class DistributionMirror(StormBase):
202 """See IDistributionMirror"""
203- _table = 'DistributionMirror'
204- _defaultOrder = ('-speed', 'name', 'id')
205-
206- owner = ForeignKey(
207- dbName='owner', foreignKey='Person',
208- storm_validator=validate_public_person, notNull=True)
209- reviewer = ForeignKey(
210- dbName='reviewer', foreignKey='Person',
211- storm_validator=validate_public_person, default=None)
212- distribution = ForeignKey(
213- dbName='distribution', foreignKey='Distribution', notNull=True)
214- name = StringCol(
215- alternateID=True, notNull=True)
216- display_name = StringCol(
217- dbName='displayname', notNull=False, default=None)
218- description = StringCol(
219- notNull=False, default=None)
220- http_base_url = StringCol(
221- notNull=False, default=None, unique=True)
222- https_base_url = StringCol(
223- notNull=False, default=None, unique=True)
224- ftp_base_url = StringCol(
225- notNull=False, default=None, unique=True)
226- rsync_base_url = StringCol(
227- notNull=False, default=None, unique=True)
228- enabled = BoolCol(
229- notNull=True, default=False)
230- speed = DBEnum(
231- allow_none=False, enum=MirrorSpeed)
232- country = ForeignKey(
233- dbName='country', foreignKey='Country', notNull=True)
234- content = DBEnum(
235- allow_none=False, enum=MirrorContent)
236- official_candidate = BoolCol(
237- notNull=True, default=False)
238+ __storm_table__ = 'DistributionMirror'
239+ __storm_order__ = ('-speed', 'name', 'id')
240+
241+ id = Int(primary=True)
242+ owner_id = Int(
243+ name='owner', validator=validate_public_person, allow_none=False)
244+ owner = Reference(owner_id, 'Person.id')
245+ reviewer_id = Int(
246+ name='reviewer', validator=validate_public_person, default=None)
247+ reviewer = Reference(reviewer_id, 'Person.id')
248+ distribution_id = Int(name='distribution', allow_none=False)
249+ distribution = Reference(distribution_id, 'Distribution.id')
250+ name = Unicode(allow_none=False)
251+ display_name = Unicode(name='displayname', allow_none=True, default=None)
252+ description = Unicode(allow_none=True, default=None)
253+ http_base_url = Unicode(allow_none=True, default=None)
254+ https_base_url = Unicode(allow_none=True, default=None)
255+ ftp_base_url = Unicode(allow_none=True, default=None)
256+ rsync_base_url = Unicode(allow_none=True, default=None)
257+ enabled = Bool(allow_none=False, default=False)
258+ speed = DBEnum(allow_none=False, enum=MirrorSpeed)
259+ country_id = Int(name='country', allow_none=False)
260+ country = Reference(country_id, 'Country.id')
261+ content = DBEnum(allow_none=False, enum=MirrorContent)
262+ official_candidate = Bool(allow_none=False, default=False)
263 status = DBEnum(
264 allow_none=False, default=MirrorStatus.PENDING_REVIEW,
265 enum=MirrorStatus)
266- date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
267- date_reviewed = UtcDateTimeCol(default=None)
268- whiteboard = StringCol(
269- notNull=False, default=None)
270- country_dns_mirror = BoolCol(
271- notNull=True, default=False)
272+ date_created = DateTime(tzinfo=pytz.UTC, allow_none=False, default=UTC_NOW)
273+ date_reviewed = DateTime(tzinfo=pytz.UTC, default=None)
274+ whiteboard = Unicode(allow_none=True, default=None)
275+ country_dns_mirror = Bool(allow_none=False, default=False)
276+
277+ def __init__(self, owner, distribution, name, speed, country, content,
278+ display_name=None, description=None, http_base_url=None,
279+ https_base_url=None, ftp_base_url=None, rsync_base_url=None,
280+ enabled=False, official_candidate=False, whiteboard=None):
281+ self.owner = owner
282+ self.distribution = distribution
283+ self.name = name
284+ self.speed = speed
285+ self.country = country
286+ self.content = content
287+ self.display_name = display_name
288+ self.description = description
289+ self.http_base_url = http_base_url
290+ self.https_base_url = https_base_url
291+ self.ftp_base_url = ftp_base_url
292+ self.rsync_base_url = rsync_base_url
293+ self.enabled = enabled
294+ self.official_candidate = official_candidate
295+ self.whiteboard = whiteboard
296
297 @property
298 def base_url(self):
299@@ -521,12 +528,12 @@ class DistributionMirror(SQLBase):
300 MirrorDistroSeriesSource.id,
301 where=(MirrorDistroSeriesSource.distribution_mirror == self),
302 order_by=(
303- MirrorDistroSeriesSource.distribution_mirrorID,
304- MirrorDistroSeriesSource.distroseriesID,
305+ MirrorDistroSeriesSource.distribution_mirror_id,
306+ MirrorDistroSeriesSource.distroseries_id,
307 Desc(MirrorDistroSeriesSource.freshness)),
308 distinct=(
309- MirrorDistroSeriesSource.distribution_mirrorID,
310- MirrorDistroSeriesSource.distroseriesID))))
311+ MirrorDistroSeriesSource.distribution_mirror_id,
312+ MirrorDistroSeriesSource.distroseries_id))))
313
314 def getSummarizedMirroredArchSeries(self):
315 """See IDistributionMirror"""
316@@ -536,12 +543,12 @@ class DistributionMirror(SQLBase):
317 MirrorDistroArchSeries.id,
318 where=(MirrorDistroArchSeries.distribution_mirror == self),
319 order_by=(
320- MirrorDistroArchSeries.distribution_mirrorID,
321- MirrorDistroArchSeries.distro_arch_seriesID,
322+ MirrorDistroArchSeries.distribution_mirror_id,
323+ MirrorDistroArchSeries.distro_arch_series_id,
324 Desc(MirrorDistroArchSeries.freshness)),
325 distinct=(
326- MirrorDistroArchSeries.distribution_mirrorID,
327- MirrorDistroArchSeries.distro_arch_seriesID))))
328+ MirrorDistroArchSeries.distribution_mirror_id,
329+ MirrorDistroArchSeries.distro_arch_series_id))))
330
331 def getExpectedPackagesPaths(self):
332 """See IDistributionMirror"""
333@@ -756,39 +763,52 @@ class _MirrorSeriesMixIn:
334
335
336 @implementer(IMirrorCDImageDistroSeries)
337-class MirrorCDImageDistroSeries(SQLBase):
338+class MirrorCDImageDistroSeries(StormBase):
339 """See IMirrorCDImageDistroSeries"""
340- _table = 'MirrorCDImageDistroSeries'
341- _defaultOrder = 'id'
342+ __storm_table__ = 'MirrorCDImageDistroSeries'
343+ __storm_order__ = 'id'
344+
345+ id = Int(primary=True)
346+ distribution_mirror_id = Int(name='distribution_mirror', allow_none=False)
347+ distribution_mirror = Reference(
348+ distribution_mirror_id, 'DistributionMirror.id')
349+ distroseries_id = Int(name='distroseries', allow_none=False)
350+ distroseries = Reference(distroseries_id, 'DistroSeries.id')
351+ flavour = Unicode(allow_none=False)
352
353- distribution_mirror = ForeignKey(
354- dbName='distribution_mirror', foreignKey='DistributionMirror',
355- notNull=True)
356- distroseries = ForeignKey(
357- dbName='distroseries', foreignKey='DistroSeries', notNull=True)
358- flavour = StringCol(notNull=True)
359+ def __init__(self, distribution_mirror, distroseries, flavour):
360+ self.distribution_mirror = distribution_mirror
361+ self.distroseries = distroseries
362+ self.flavour = flavour
363
364
365 @implementer(IMirrorDistroArchSeries)
366-class MirrorDistroArchSeries(SQLBase, _MirrorSeriesMixIn):
367+class MirrorDistroArchSeries(StormBase, _MirrorSeriesMixIn):
368 """See IMirrorDistroArchSeries"""
369- _table = 'MirrorDistroArchSeries'
370- _defaultOrder = [
371+ __storm_table__ = 'MirrorDistroArchSeries'
372+ __storm_order__ = [
373 'distroarchseries', 'component', 'pocket', 'freshness', 'id']
374
375- distribution_mirror = ForeignKey(
376- dbName='distribution_mirror', foreignKey='DistributionMirror',
377- notNull=True)
378- distro_arch_series = ForeignKey(
379- dbName='distroarchseries', foreignKey='DistroArchSeries',
380- notNull=True)
381- component = ForeignKey(
382- dbName='component', foreignKey='Component', notNull=True)
383+ id = Int(primary=True)
384+ distribution_mirror_id = Int(name='distribution_mirror', allow_none=False)
385+ distribution_mirror = Reference(
386+ distribution_mirror_id, 'DistributionMirror.id')
387+ distro_arch_series_id = Int(name='distroarchseries', allow_none=False)
388+ distro_arch_series = Reference(
389+ distro_arch_series_id, 'DistroArchSeries.id')
390+ component_id = Int(name='component', allow_none=False)
391+ component = Reference(component_id, 'Component.id')
392 freshness = DBEnum(
393 allow_none=False, default=MirrorFreshness.UNKNOWN,
394 enum=MirrorFreshness)
395- pocket = DBEnum(
396- allow_none=False, enum=PackagePublishingPocket)
397+ pocket = DBEnum(allow_none=False, enum=PackagePublishingPocket)
398+
399+ def __init__(self, distribution_mirror, distro_arch_series, component,
400+ pocket):
401+ self.distribution_mirror = distribution_mirror
402+ self.distro_arch_series = distro_arch_series
403+ self.component = component
404+ self.pocket = pocket
405
406 def getLatestPublishingEntry(self, time_interval, deb_only=True):
407 """Return the BinaryPackagePublishingHistory record with the
408@@ -847,24 +867,30 @@ class MirrorDistroArchSeries(SQLBase, _MirrorSeriesMixIn):
409
410
411 @implementer(IMirrorDistroSeriesSource)
412-class MirrorDistroSeriesSource(SQLBase, _MirrorSeriesMixIn):
413+class MirrorDistroSeriesSource(StormBase, _MirrorSeriesMixIn):
414 """See IMirrorDistroSeriesSource"""
415- _table = 'MirrorDistroSeriesSource'
416- _defaultOrder = ['distroseries', 'component', 'pocket', 'freshness', 'id']
417-
418- distribution_mirror = ForeignKey(
419- dbName='distribution_mirror', foreignKey='DistributionMirror',
420- notNull=True)
421- distroseries = ForeignKey(
422- dbName='distroseries', foreignKey='DistroSeries',
423- notNull=True)
424- component = ForeignKey(
425- dbName='component', foreignKey='Component', notNull=True)
426+ __storm_table__ = 'MirrorDistroSeriesSource'
427+ __storm_order__ = [
428+ 'distroseries', 'component', 'pocket', 'freshness', 'id']
429+
430+ id = Int(primary=True)
431+ distribution_mirror_id = Int(name='distribution_mirror', allow_none=False)
432+ distribution_mirror = Reference(
433+ distribution_mirror_id, 'DistributionMirror.id')
434+ distroseries_id = Int(name='distroseries', allow_none=False)
435+ distroseries = Reference(distroseries_id, 'DistroSeries.id')
436+ component_id = Int(name='component', allow_none=False)
437+ component = Reference(component_id, 'Component.id')
438 freshness = DBEnum(
439 allow_none=False, default=MirrorFreshness.UNKNOWN,
440 enum=MirrorFreshness)
441- pocket = DBEnum(
442- allow_none=False, enum=PackagePublishingPocket)
443+ pocket = DBEnum(allow_none=False, enum=PackagePublishingPocket)
444+
445+ def __init__(self, distribution_mirror, distroseries, component, pocket):
446+ self.distribution_mirror = distribution_mirror
447+ self.distroseries = distroseries
448+ self.component = component
449+ self.pocket = pocket
450
451 def getLatestPublishingEntry(self, time_interval):
452 clauses = [
453@@ -909,14 +935,20 @@ class MirrorDistroSeriesSource(SQLBase, _MirrorSeriesMixIn):
454
455
456 @implementer(IMirrorProbeRecord)
457-class MirrorProbeRecord(SQLBase):
458+class MirrorProbeRecord(StormBase):
459 """See IMirrorProbeRecord"""
460- _table = 'MirrorProbeRecord'
461- _defaultOrder = 'id'
462-
463- distribution_mirror = ForeignKey(
464- dbName='distribution_mirror', foreignKey='DistributionMirror',
465- notNull=True)
466- log_file = ForeignKey(
467- dbName='log_file', foreignKey='LibraryFileAlias', notNull=True)
468- date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW)
469+ __storm_table__ = 'MirrorProbeRecord'
470+ __storm_order__ = 'id'
471+
472+ id = Int(primary=True)
473+ distribution_mirror_id = Int(name='distribution_mirror', allow_none=False)
474+ distribution_mirror = Reference(
475+ distribution_mirror_id, 'DistributionMirror.id')
476+ log_file_id = Int(name='log_file', allow_none=False)
477+ log_file = Reference(log_file_id, 'LibraryFileAlias.id')
478+ date_created = DateTime(
479+ tzinfo=pytz.UTC, allow_none=False, default=UTC_NOW)
480+
481+ def __init__(self, distribution_mirror, log_file):
482+ self.distribution_mirror = distribution_mirror
483+ self.log_file = log_file

Subscribers

People subscribed via source and target branches

to status/vote changes: