Merge lp://staging/~jpds/launchpad/fix_361650 into lp://staging/launchpad
- fix_361650
- Merge into devel
Status: | Rejected |
---|---|
Rejected by: | Curtis Hovey |
Proposed branch: | lp://staging/~jpds/launchpad/fix_361650 |
Merge into: | lp://staging/launchpad |
Diff against target: |
545 lines (+306/-19) 12 files modified
database/sampledata/current-dev.sql (+6/-0) database/sampledata/current.sql (+6/-0) database/schema/comments.sql (+1/-0) database/schema/patch-2207-20-0.sql (+19/-0) lib/lp/registry/browser/distributionmirror.py (+63/-4) lib/lp/registry/browser/tests/distributionmirror-views.txt (+1/-1) lib/lp/registry/configure.zcml (+1/-1) lib/lp/registry/interfaces/distributionmirror.py (+9/-1) lib/lp/registry/model/distributionmirror.py (+22/-0) lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt (+162/-11) lib/lp/registry/templates/distributionmirror-index.pt (+9/-0) lib/lp/registry/templates/distributionmirror-macros.pt (+7/-1) |
To merge this branch: | bzr merge lp://staging/~jpds/launchpad/fix_361650 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Curtis Hovey (community) | ui and code | Needs Fixing | |
Jonathan Lange (community) | db | Approve | |
Michael Nelson (community) | ui | Needs Information | |
Stuart Bishop (community) | db | Approve | |
Canonical Launchpad Engineering | code | Pending | |
Review via email: mp+16749@code.staging.launchpad.net |
Commit message
Description of the change
Jonathan Davies (jpds) wrote : | # |
Jonathan Lange (jml) wrote : | # |
Hello Jonathan,
Thanks for this patch -- I can see how this would be useful.
I don't have any serious issues with the database patch -- the uniqueness constraint looks correct to me. My main concern is that using the word 'official' to describe this new concept will create confusion with the already existing concept of 'official mirror'. Would 'primary_mirror' make sense?
Other than that, the db patch looks good to me.
jml
Stuart Bishop (stub) wrote : | # |
I don't much like the column name either, but it does match the domain language used at http://
Why are we limiting things to one official country mirror per country? Is there a technical issue we need to ensure doesn't happen, or is this an arbitrary choice made by us or the mirror maintainers?
Patch number is patch-2207-
Stuart Bishop (stub) wrote : | # |
> I don't much like the column name either, but it does match the domain
> language used at http://
> correct.
>
> Why are we limiting things to one official country mirror per country? Is
> there a technical issue we need to ensure doesn't happen, or is this an
> arbitrary choice made by us or the mirror maintainers?
>
> Patch number is patch-2207-
> the UNIQUE constraints are actually desirable.
One thing that needs changing - You should use 'IS TRUE' and 'IS FALSE' rather than '= TRUE' or '= FALSE'. = and IS give different results in SQL's three valued boolean arithmetic which can confuse the query planner since it isn't as smart as you.
Jonathan Davies (jpds) wrote : | # |
Morning Jonathan,
Country mirrors are official mirrors whose FQDNs have been CNAME'ed to a $CC.[archive,
Stuart,
We're limited to one country mirror because it's not possible to load balance between two different Ubuntu archives mirrors because of limitations with the apt-get software unless the two mirrors are in perfect sync.
Also I believe, the plan is to, hopefully, auto-generate our CNAME DNS records of country mirrors using the ones specified in LP's DB by admins (with this patch). And it's not possible to have multiple CNAME records to a FQDN.
Michael Nelson (michael.nelson) wrote : | # |
Hi Jonothan, thanks for yet another long-awaited feature :)
I'd really like to get Curtis to look at this one, although I've got a few comments.
The first question that came to my mind was, why is this another separate form (currently there is "Change details", "Review", and now "Set/Unset as country mirror".
I personally wonder whether the 'Review' form could accommodate this (perhaps renamed with something that implied official and/or country-mirror status?), so that both items could be presented and dealt with there on the one form. This would also alleviate the need for the changing menu item name ('Set/Unset'). But Curtis might have other ideas.
Also, when editing the mirror after setting it as a country mirror, the validation is great (for country/
IRC snippet:
<noodles775> jpds: what's the reasoning behind not doing this as an admin-only field displayed on the normal edit form?
<jpds> noodles775: Do you mean the +review form?
<noodles775> jpds: no, I meant the +edit form (but i'm logged in as an admin, maybe that's not presented for mirror-admins...). Checking now.
<jpds> noodles775: I wanted to make it a little obvious by having the separate button for it.
<jpds> noodles775: And mirror registrants shouldn't be able to see the checkbox themselves.
Michael Nelson (michael.nelson) wrote : | # |
> Also, when editing the mirror after setting it as a country mirror, the
> validation is great (for country/
> redirect back to the +index page, but instead +country-mirror form itself?
Sorry, that's very unclear (and incorrect). What I meant was, once you have set a mirror as a country mirror, when you then go back and change the details (on the +edit page), the validation there is great for country/
Jonathan Lange (jml) wrote : | # |
OK, since it matches the existing documented domain language, I'm happy with the column name.
Curtis Hovey (sinzui) wrote : | # |
Hi Johnathan.
Thanks for undertaking this large effort.
I reviewed the code and the UI. There is a lot that needs fixing, but I
can help with some of it.
Starting with the UI.
I like your change to move country_dns_mirror to +edit, but per your original
concern, it is not obvious that the mirror admin uses this page to change the
state. We strive to move edit and view links into the page where the
information is presented so that it is clear to the user that he can change
what he is reading. This is a simple one-line addition to the template.
However, the addition of a new portlet makes the layout worse. This page
has known issues because it was one of the first to be changed for 3.0,
but it was not updated as 3.0 style evolved. The registration and status
information are not in their correct places: the registering slot and the
Mirror information portlet. If they were, the addition of the new field
would be easy and obvious. I tinkered with the template to fix the layout
and I have a diff that you can apply to your branch to get these changes.
In the fixed layout, the official country dns status appears higher on
the page and I think that is good.
Suggested layout: http://
Diff to revise layout: http://
I do not like the info notifications. They make me worry that my other
changes were not accepted. Since the form did what I asked it to, there
is no need to take such an extraordinary measure. I think they should be
removed.
I pondered the addition of the star to the mirrors list. Your approach is
just like badges that are applied to bugs, so I think it is correct. I think
my misgivings are from my unfamiliarity with the star as an icon. I did
learn it was official when I placed my mouse over it. I think we can leave
it as is.
BTW. There is a problem with this merge proposal. It must be merged into
db-devel since the schema changes are incompatible with lpnet/edge. If you
had proposed the merge with db-devel you would have seen that your db
patch conflicts. You need to rename it and update it as suggested by Stuart
before this can be tested properly.
> === modified file 'lib/lp/
> --- lib/lp/
> +++ lib/lp/
...
> @@ -275,10 +278,66 @@
> """See `LaunchpadFormV
> return canonical_
>
> + def validate(self, data):
> + dns_mirror_choice = data.get(
> +
> + # This mirror has not been marked as a country mirror.
> + if dns_mirror_choice == True:
> + # Safe-guard against multiple country mirrors for one country.
> + current_
> + getUtility(
> + self.context.
> +
> + # User has decided to mark it as one.
> + if current_
> + # There are none - mark this one as the one.
> + sel...
Jonathan Lange (jml) wrote : | # |
Curtis & Michael, I can't believe that you _both_ spelled Jonathan's name incorrectly. :P
Michael Nelson (michael.nelson) wrote : | # |
On Fri, Jan 8, 2010 at 5:59 AM, Jonathan Lange <email address hidden> wrote:
> Curtis & Michael, I can't believe that you _both_ spelled Jonathan's name incorrectly. :P
Sorry Jonathan... too many Aussie friends who go by "Jono" :/
> --
> https:/
> You are reviewing the proposed merge of lp:~jpds/launchpad/fix_361650 into lp:launchpad/devel.
>
Graham Binns (gmb) wrote : | # |
Can someone who knows the situation of this branch update its status? It'd be great if it was either WIP or Approved, just to get it out of the "reviews I can do" queue...
Curtis Hovey (sinzui) wrote : | # |
I rejected this branch because the implementation and testing were unviable. Johnathan. Has landed the schema change and some prerequisite branches per my advice. His replacement branch to land this feature as a model change is in review.
Preview Diff
1 | === modified file 'database/sampledata/current-dev.sql' |
2 | --- database/sampledata/current-dev.sql 2009-12-14 13:49:03 +0000 |
3 | +++ database/sampledata/current-dev.sql 2010-01-05 15:14:20 +0000 |
4 | @@ -2219,6 +2219,9 @@ |
5 | INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (8, 1, 'canonical-archive', 'http://archive.ubuntu.com/ubuntu/', NULL, NULL, NULL, NULL, 1, 70, 225, 1, true, true, '2006-10-16 18:31:43.434567', NULL, 30, NULL, NULL); |
6 | INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (9, 1, 'canonical-releases', 'http://releases.ubuntu.com/', NULL, NULL, NULL, NULL, 1, 70, 225, 2, true, true, '2006-10-16 18:31:43.434567', NULL, 30, NULL, NULL); |
7 | INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (10, 1, 'random-releases-mirror', 'http://releases.random.com/', NULL, NULL, NULL, NULL, 1, 70, 225, 2, true, true, '2006-10-16 18:31:43.434567', NULL, 10, NULL, NULL); |
8 | +INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (11, 1, 'mirror.davis.antarctica.org-archive', 'http://mirror.davis.antarctica.org/ubuntu', NULL, NULL, 'Davis Station', NULL, 1, 70, 9, 1, true, true, '2010-01-03 00:07:44.412317', NULL, 30, NULL, NULL); |
9 | +INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (12, 1, 'ubuntu.mirror.tudos.de-archive', 'http://ubuntu.mirror.tudos.de/ubuntu', NULL, 'rsync://ubuntu.mirror.tudos.de/ubuntu', 'Technische Universität Dresden', NULL, 12, 110, 82, 1, true, true, '2010-01-03 01:48:02.93419', NULL, 30, NULL, NULL); |
10 | +INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (13, 1, 'mirror.mawson.antarctica.org-releases', 'http://mirror.mawson.antarctica.org/ubuntu-releases', NULL, NULL, 'Mawson Station', NULL, 1, 70, 9, 2, true, true, '2010-01-03 02:05:10.424767', NULL, 30, NULL, NULL); |
11 | |
12 | |
13 | ALTER TABLE distributionmirror ENABLE TRIGGER ALL; |
14 | @@ -4857,6 +4860,9 @@ |
15 | |
16 | INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (1, 6, 46, '2006-05-24 17:11:59.37369'); |
17 | INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (2, 7, 47, '2006-05-24 17:12:03.714206'); |
18 | +INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (3, 11, 47, '2010-01-03 00:20:30.412312'); |
19 | +INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (4, 12, 46, '2010-01-03 01:49:27.432231'); |
20 | +INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (5, 13, 47, '2010-01-03 02:07:17.434121'); |
21 | |
22 | |
23 | ALTER TABLE mirrorproberecord ENABLE TRIGGER ALL; |
24 | |
25 | === modified file 'database/sampledata/current.sql' |
26 | --- database/sampledata/current.sql 2009-12-14 13:49:03 +0000 |
27 | +++ database/sampledata/current.sql 2010-01-05 15:14:20 +0000 |
28 | @@ -2201,6 +2201,9 @@ |
29 | INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (8, 1, 'canonical-archive', 'http://archive.ubuntu.com/ubuntu/', NULL, NULL, NULL, NULL, 1, 70, 225, 1, true, true, '2006-10-16 18:31:43.434567', NULL, 30, NULL, NULL); |
30 | INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (9, 1, 'canonical-releases', 'http://releases.ubuntu.com/', NULL, NULL, NULL, NULL, 1, 70, 225, 2, true, true, '2006-10-16 18:31:43.434567', NULL, 30, NULL, NULL); |
31 | INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (10, 1, 'random-releases-mirror', 'http://releases.random.com/', NULL, NULL, NULL, NULL, 1, 70, 225, 2, true, true, '2006-10-16 18:31:43.434567', NULL, 10, NULL, NULL); |
32 | +INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (11, 1, 'mirror.davis.antarctica.org-archive', 'http://mirror.davis.antarctica.org/ubuntu', NULL, NULL, 'Davis Station', NULL, 1, 70, 9, 1, true, true, '2010-01-03 00:07:44.412317', NULL, 30, NULL, NULL); |
33 | +INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (12, 1, 'ubuntu.mirror.tudos.de-archive', 'http://ubuntu.mirror.tudos.de/ubuntu', NULL, 'rsync://ubuntu.mirror.tudos.de/ubuntu', 'Technische Universität Dresden', NULL, 12, 110, 82, 1, true, true, '2010-01-03 01:48:02.93419', NULL, 30, NULL, NULL); |
34 | +INSERT INTO distributionmirror (id, distribution, name, http_base_url, ftp_base_url, rsync_base_url, displayname, description, owner, speed, country, content, official_candidate, enabled, date_created, whiteboard, status, date_reviewed, reviewer) VALUES (13, 1, 'mirror.mawson.antarctica.org-releases', 'http://mirror.mawson.antarctica.org/ubuntu-releases', NULL, NULL, 'Mawson Station', NULL, 1, 70, 9, 2, true, true, '2010-01-03 02:05:10.424767', NULL, 30, NULL, NULL); |
35 | |
36 | |
37 | ALTER TABLE distributionmirror ENABLE TRIGGER ALL; |
38 | @@ -4776,6 +4779,9 @@ |
39 | |
40 | INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (1, 6, 46, '2006-05-24 17:11:59.37369'); |
41 | INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (2, 7, 47, '2006-05-24 17:12:03.714206'); |
42 | +INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (3, 11, 47, '2010-01-03 00:20:30.412312'); |
43 | +INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (4, 12, 46, '2010-01-03 01:49:27.432231'); |
44 | +INSERT INTO mirrorproberecord (id, distribution_mirror, log_file, date_created) VALUES (5, 13, 47, '2010-01-03 02:07:17.434121'); |
45 | |
46 | |
47 | ALTER TABLE mirrorproberecord ENABLE TRIGGER ALL; |
48 | |
49 | === modified file 'database/schema/comments.sql' |
50 | --- database/schema/comments.sql 2009-12-01 13:45:58 +0000 |
51 | +++ database/schema/comments.sql 2010-01-05 15:14:20 +0000 |
52 | @@ -1794,6 +1794,7 @@ |
53 | COMMENT ON COLUMN DistributionMirror.whiteboard IS 'Notes on the current status of the mirror'; |
54 | COMMENT ON COLUMN DistributionMirror.date_created IS 'The date and time the mirror was created.'; |
55 | COMMENT ON COLUMN DistributionMirror.date_reviewed IS 'The date and time the mirror was reviewed.'; |
56 | +COMMENT ON COLUMN DistributionMirror.country_dns_mirror IS 'Is the mirror an country mirror in DNS?'; |
57 | |
58 | -- MirrorDistroArchSeries |
59 | COMMENT ON TABLE MirrorDistroArchSeries IS 'The mirror of the packages of a given Distro Arch Release.'; |
60 | |
61 | === added file 'database/schema/patch-2207-20-0.sql' |
62 | --- database/schema/patch-2207-20-0.sql 1970-01-01 00:00:00 +0000 |
63 | +++ database/schema/patch-2207-20-0.sql 2010-01-05 15:14:20 +0000 |
64 | @@ -0,0 +1,19 @@ |
65 | +-- Copyright 2010 Canonical Ltd. This software is licensed under the |
66 | +-- GNU Affero General Public License version 3 (see the file LICENSE). |
67 | + |
68 | +SET client_min_messages=ERROR; |
69 | + |
70 | +ALTER TABLE DistributionMirror |
71 | + ADD COLUMN country_dns_mirror boolean DEFAULT FALSE NOT NULL; |
72 | + |
73 | +--- Index for archive mirrors. |
74 | +CREATE UNIQUE INDEX distributionmirror__archive__distribution__country__key |
75 | +ON DistributionMirror(distribution, country, content) |
76 | +WHERE country_dns_mirror IS TRUE AND content = 1; |
77 | + |
78 | +--- Index for releases mirrors. |
79 | +CREATE UNIQUE INDEX distributionmirror__releases__distribution__country__key |
80 | +ON DistributionMirror(distribution, country, content) |
81 | +WHERE country_dns_mirror IS TRUE AND content = 2; |
82 | + |
83 | +INSERT INTO LaunchpadDatabaseRevision VALUES (2207, 20, 0); |
84 | |
85 | === modified file 'lib/lp/registry/browser/distributionmirror.py' |
86 | --- lib/lp/registry/browser/distributionmirror.py 2009-12-12 22:15:31 +0000 |
87 | +++ lib/lp/registry/browser/distributionmirror.py 2010-01-05 15:14:20 +0000 |
88 | @@ -18,6 +18,7 @@ |
89 | from datetime import datetime |
90 | import pytz |
91 | |
92 | +from zope.component import getUtility |
93 | from zope.lifecycleevent import ObjectCreatedEvent |
94 | from zope.event import notify |
95 | from zope.interface import implements |
96 | @@ -32,7 +33,8 @@ |
97 | from lp.registry.interfaces.distribution import ( |
98 | IDistributionMirrorMenuMarker) |
99 | from lp.registry.interfaces.distributionmirror import ( |
100 | - IDistributionMirror) |
101 | + IDistributionMirror, IDistributionMirrorSet) |
102 | +from canonical.launchpad.webapp.authorization import check_permission |
103 | from canonical.launchpad.webapp.batching import BatchNavigator |
104 | from canonical.launchpad.webapp.publisher import LaunchpadView |
105 | from canonical.launchpad.webapp import ( |
106 | @@ -259,7 +261,8 @@ |
107 | schema = IDistributionMirror |
108 | field_names = ["name", "displayname", "description", "whiteboard", |
109 | "http_base_url", "ftp_base_url", "rsync_base_url", "speed", |
110 | - "country", "content", "official_candidate"] |
111 | + "country", "content", "official_candidate", |
112 | + "country_dns_mirror"] |
113 | @property |
114 | def label(self): |
115 | """See `LaunchpadFormView`.""" |
116 | @@ -275,10 +278,66 @@ |
117 | """See `LaunchpadFormView`.""" |
118 | return canonical_url(self.context) |
119 | |
120 | + def validate(self, data): |
121 | + dns_mirror_choice = data.get('country_dns_mirror') |
122 | + |
123 | + # This mirror has not been marked as a country mirror. |
124 | + if dns_mirror_choice == True: |
125 | + # Safe-guard against multiple country mirrors for one country. |
126 | + current_country_mirror = ( |
127 | + getUtility(IDistributionMirrorSet).getCountryMirrorForCountry( |
128 | + self.context.country, self.context.content)) |
129 | + |
130 | + # User has decided to mark it as one. |
131 | + if current_country_mirror is None: |
132 | + # There are none - mark this one as the one. |
133 | + self.request.response.addInfoNotification( |
134 | + "The mirror %s has been set as the country DNS mirror for " |
135 | + "%s." % (self.context.title, self.context.country.name)) |
136 | + elif current_country_mirror == self.context: |
137 | + return # We are editing the country DNS mirror. |
138 | + else: |
139 | + # Make sure that there isn't already a mirror for this |
140 | + # country already. |
141 | + self.setFieldError("country_dns_mirror", "%s already " |
142 | + "has a country DNS mirror set, please unset the country " |
143 | + "DNS mirror status of %s before continuing." % ( |
144 | + self.context.country.name, |
145 | + current_country_mirror.title)) |
146 | + elif dns_mirror_choice == False and self.context.country_dns_mirror: |
147 | + self.request.response.addInfoNotification( |
148 | + "The mirror %s has been unset as the country DNS mirror for " |
149 | + "%s." % (self.context.title, self.context.country.name)) |
150 | + |
151 | + def setUpFields(self): |
152 | + super(DistributionMirrorEditView, self).setUpFields() |
153 | + |
154 | + is_admin = check_permission('launchpad.Admin', self.context) |
155 | + |
156 | + mirror_qualifies = ( |
157 | + self.context.last_probe_record is not None |
158 | + and self.context.isOfficial() |
159 | + and self.context.http_base_url is not None) |
160 | + |
161 | + # User must be an admin and the mirror must pass the above. |
162 | + if not is_admin or not mirror_qualifies: |
163 | + self.form_fields = self.form_fields.omit('country_dns_mirror') |
164 | + |
165 | @action(_("Save"), name="save") |
166 | def action_save(self, action, data): |
167 | - self.updateContextFromData(data) |
168 | - self.next_url = canonical_url(self.context) |
169 | + # Ensure that we are not changing an archive mirror to a releases one |
170 | + # and that it's a country mirror at the same time. |
171 | + if data.get('content') != self.context.content: |
172 | + if self.context.country_dns_mirror: |
173 | + self.setFieldError("content", "Changing the mirror content " |
174 | + "type of country DNS mirrors is forbidden.") |
175 | + elif data.get('country') != self.context.country: |
176 | + if self.context.country_dns_mirror: |
177 | + self.setFieldError("country", "Changing the country of country " |
178 | + "DNS mirrors is forbidden.") |
179 | + else: |
180 | + self.updateContextFromData(data) |
181 | + self.next_url = canonical_url(self.context) |
182 | |
183 | |
184 | class DistributionMirrorReassignmentView(ObjectReassignmentView): |
185 | |
186 | === modified file 'lib/lp/registry/browser/tests/distributionmirror-views.txt' |
187 | --- lib/lp/registry/browser/tests/distributionmirror-views.txt 2009-12-14 15:22:53 +0000 |
188 | +++ lib/lp/registry/browser/tests/distributionmirror-views.txt 2010-01-05 15:14:20 +0000 |
189 | @@ -243,7 +243,7 @@ |
190 | >>> view.field_names |
191 | ['name', 'displayname', 'description', 'whiteboard', 'http_base_url', |
192 | 'ftp_base_url', 'rsync_base_url', 'speed', 'country', 'content', |
193 | - 'official_candidate'] |
194 | + 'official_candidate', 'country_dns_mirror'] |
195 | |
196 | >>> print mirror.ftp_base_url |
197 | None |
198 | |
199 | === modified file 'lib/lp/registry/configure.zcml' |
200 | --- lib/lp/registry/configure.zcml 2009-12-09 14:55:02 +0000 |
201 | +++ lib/lp/registry/configure.zcml 2010-01-05 15:14:20 +0000 |
202 | @@ -1611,7 +1611,7 @@ |
203 | speed country content official_candidate owner" /> |
204 | <require |
205 | permission="launchpad.Admin" |
206 | - set_attributes="status reviewer date_reviewed" |
207 | + set_attributes="status reviewer date_reviewed country_dns_mirror" |
208 | attributes="destroySelf" /> |
209 | </class> |
210 | |
211 | |
212 | === modified file 'lib/lp/registry/interfaces/distributionmirror.py' |
213 | --- lib/lp/registry/interfaces/distributionmirror.py 2009-10-26 18:40:04 +0000 |
214 | +++ lib/lp/registry/interfaces/distributionmirror.py 2010-01-05 15:14:20 +0000 |
215 | @@ -330,8 +330,11 @@ |
216 | 'mirror of packages for this distribution.'), |
217 | vocabulary=MirrorContent) |
218 | official_candidate = Bool( |
219 | - title=_('Apply to be an official mirror of this distribution'), |
220 | + title=_('Apply to be an official mirror of this distribution.'), |
221 | required=False, readonly=False, default=True) |
222 | + country_dns_mirror = Bool( |
223 | + title=_('Set this mirror as an country DNS mirror.'), |
224 | + required=False, readonly=False, default=False) |
225 | status = Choice( |
226 | title=_('Status'), required=True, readonly=False, |
227 | vocabulary=MirrorStatus) |
228 | @@ -536,6 +539,11 @@ |
229 | def getByRsyncUrl(url): |
230 | """Return the mirror with the given Rsync URL or None.""" |
231 | |
232 | + def getCountryMirrorForCountry(country, mirror_type): |
233 | + """Return the country mirror for a certain country for the specified |
234 | + mirror type. |
235 | + """ |
236 | + |
237 | |
238 | class IMirrorDistroArchSeries(Interface): |
239 | """The mirror of the packages of a given Distro Arch Series""" |
240 | |
241 | === modified file 'lib/lp/registry/model/distributionmirror.py' |
242 | --- lib/lp/registry/model/distributionmirror.py 2009-10-26 18:40:04 +0000 |
243 | +++ lib/lp/registry/model/distributionmirror.py 2010-01-05 15:14:20 +0000 |
244 | @@ -94,6 +94,8 @@ |
245 | notNull=True, enum=MirrorContent) |
246 | official_candidate = BoolCol( |
247 | notNull=True, default=False) |
248 | + country_dns_mirror = BoolCol( |
249 | + notNull=True, default=False) |
250 | status = EnumCol( |
251 | notNull=True, default=MirrorStatus.PENDING_REVIEW, enum=MirrorStatus) |
252 | date_created = UtcDateTimeCol(notNull=True, default=UTC_NOW) |
253 | @@ -402,6 +404,26 @@ |
254 | """See IDistributionMirrorSet""" |
255 | return DistributionMirror.get(mirror_id) |
256 | |
257 | + def getCountryMirrorForCountry(self, country, mirror_type): |
258 | + """See IDistributionMirrorSet.""" |
259 | + country_id = None |
260 | + if country is not None: |
261 | + country_id = country.id |
262 | + |
263 | + base_query = AND( |
264 | + DistributionMirror.q.content == mirror_type, |
265 | + DistributionMirror.q.enabled == True, |
266 | + DistributionMirror.q.http_base_url != None, |
267 | + DistributionMirror.q.official_candidate == True, |
268 | + DistributionMirror.q.status == MirrorStatus.OFFICIAL, |
269 | + DistributionMirror.q.country_dns_mirror == True) |
270 | + |
271 | + query = AND(DistributionMirror.q.countryID == country_id, base_query) |
272 | + |
273 | + country_mirror = DistributionMirror.selectOne(query) |
274 | + |
275 | + return country_mirror |
276 | + |
277 | def getBestMirrorsForCountry(self, country, mirror_type): |
278 | """See IDistributionMirrorSet""" |
279 | # As per mvo's request we only return mirrors which have an |
280 | |
281 | === modified file 'lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt' |
282 | --- lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt 2009-12-10 23:32:13 +0000 |
283 | +++ lib/lp/registry/stories/distributionmirror/xx-distribution-mirrors.txt 2010-01-05 15:14:20 +0000 |
284 | @@ -41,12 +41,16 @@ |
285 | Mirrors of Ubuntu Linux... |
286 | >>> print_mirrors_by_countries(browser.contents) |
287 | Antarctica: |
288 | - [(u'Archive-mirror2', u'http', u'128 Kbps', u'Six hours behind')] |
289 | + [(u'Davis Station', u'', u'http', u'100 Mbps', u'Last update unknown'), |
290 | + (u'Archive-mirror2', u'', u'http', u'128 Kbps', u'Six hours behind')] |
291 | France: |
292 | - [(u'Archive-404-mirror', u'http', u'512 Kbps', u'Last update unknown'), |
293 | - (u'Archive-mirror', u'http', u'128 Kbps', u'Last update unknown')] |
294 | + [(u'Archive-404-mirror', u'', u'http', u'512 Kbps', u'Last update unknown'), |
295 | + (u'Archive-mirror', u'', u'http', u'128 Kbps', u'Last update unknown')] |
296 | + Germany: |
297 | + [(u'Technische Universit\xe4t Dresden', u'', u'http\nrsync', u'10 Gbps', |
298 | + u'Last update unknown')] |
299 | United Kingdom: |
300 | - [(u'Canonical-archive', u'http', u'100 Mbps', u'Last update unknown')] |
301 | + [(u'Canonical-archive', u'', u'http', u'100 Mbps', u'Last update unknown')] |
302 | >>> find_tags_by_class(browser.contents, 'distromirrorstatusSIXHOURSBEHIND') |
303 | [<span class="distromirrorstatusSIXHOURSBEHIND">Six hours behind</span>] |
304 | >>> find_tags_by_class(browser.contents, 'distromirrorstatusUNKNOWN')[0] |
305 | @@ -59,13 +63,160 @@ |
306 | >>> browser.url |
307 | 'http://launchpad.dev/ubuntu/+cdmirrors' |
308 | >>> print_mirrors_by_countries(browser.contents) |
309 | + Antarctica: [(u'Mawson Station', u'', u'http', u'100 Mbps')] |
310 | France: |
311 | - [(u'Releases-mirror', u'http', u'2 Mbps'), |
312 | - (u'Unreachable-mirror', u'http', u'512 Kbps')] |
313 | + [(u'Releases-mirror', u'', u'http', u'2 Mbps'), |
314 | + (u'Unreachable-mirror', u'', u'http', u'512 Kbps')] |
315 | Germany: |
316 | - [(u'Releases-mirror2', u'http', u'2 Mbps')] |
317 | + [(u'Releases-mirror2', u'', u'http', u'2 Mbps')] |
318 | United Kingdom: |
319 | - [(u'Canonical-releases', u'http', u'100 Mbps')] |
320 | + [(u'Canonical-releases', u'', u'http', u'100 Mbps')] |
321 | + |
322 | + |
323 | +=== Country DNS mirrors === |
324 | + |
325 | +Country DNS mirrors are official mirrors whose FQDN have been CNAME'd for |
326 | +domain records such as gb.archive.ubuntu.com. They are highly reliable and set |
327 | +during installation, depending on which country the user specified they were |
328 | +in. |
329 | + |
330 | +Mirror listing administrators are the ones with the authority to set mirrors as |
331 | +country mirrors. |
332 | + |
333 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
334 | + >>> browser.open('https://launchpad.dev/ubuntu/+mirror/archive-mirror2') |
335 | + >>> browser.getLink("Change details").click() |
336 | + >>> print browser.title |
337 | + Edit mirror Archive-mirror2... |
338 | + >>> browser.getControl(name='field.country_dns_mirror').value = True |
339 | + >>> browser.getControl('Save').click() |
340 | + >>> print find_tags_by_class(browser.contents, 'informational message')[0] |
341 | + <div class="informational message">The mirror Archive-mirror2 has been set as |
342 | + the country DNS mirror for Antarctica.</div> |
343 | + >>> print find_tag_by_id(browser.contents, 'maincontent').renderContents() |
344 | + <BLANKLINE> |
345 | + ...Country DNS mirror... |
346 | + <BLANKLINE> |
347 | + ...This mirror is the country DNS mirror for <span>Antarctica</span>... |
348 | + |
349 | +And also to unset mirrors as country mirrors: |
350 | + |
351 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
352 | + >>> browser.open('https://launchpad.dev/ubuntu/+mirror/archive-mirror2') |
353 | + >>> browser.getLink("Change details").click() |
354 | + >>> print browser.title |
355 | + Edit mirror Archive-mirror2... |
356 | + >>> browser.getControl(name='field.country_dns_mirror').value = False |
357 | + >>> browser.getControl('Save').click() |
358 | + >>> print find_tags_by_class(browser.contents, 'informational message')[0] |
359 | + <div class="informational message">The mirror Archive-mirror2 has been |
360 | + unset as the country DNS mirror for Antarctica.</div> |
361 | + |
362 | +Unofficial/pending-review mirrors may not be set as country mirrors: |
363 | + |
364 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
365 | + >>> browser.open('https://launchpad.dev/ubuntu/+mirror/invalid-mirror/+edit') |
366 | + >>> browser.getControl( |
367 | + ... name='field.country_dns_mirror').value = True |
368 | + Traceback (most recent call last): |
369 | + ... |
370 | + LookupError: name 'field.country_dns_mirror' |
371 | + |
372 | +Mirror registrants may not make changes to country DNS mirrors settings: |
373 | + |
374 | + >>> browser_mirror_registrant = setupBrowser( |
375 | + ... auth='Basic test@canonical.com:test') |
376 | + >>> browser_mirror_registrant.open( |
377 | + ... 'https://launchpad.dev/ubuntu/+mirror/ubuntu.mirror.tudos.de-archive/+edit') |
378 | + >>> browser_mirror_registrant.getControl( |
379 | + ... name='field.country_dns_mirror').value = True |
380 | + Traceback (most recent call last): |
381 | + ... |
382 | + LookupError: name 'field.country_dns_mirror' |
383 | + |
384 | +A country may not have more than one country content-type mirror, for example, |
385 | +archive mirrors: |
386 | + |
387 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
388 | + >>> browser.open( |
389 | + ... 'https://launchpad.dev/ubuntu/+mirror/mirror.davis.antarctica.org-archive') |
390 | + >>> browser.getLink("Change details").click() |
391 | + >>> print browser.title |
392 | + Edit mirror Davis Station... |
393 | + >>> browser.getControl(name='field.country_dns_mirror').value = True |
394 | + >>> browser.getControl('Save').click() |
395 | + >>> print find_tags_by_class(browser.contents, 'informational message')[0] |
396 | + <div class="informational message">The mirror Davis Station has been set |
397 | + as the country DNS mirror for Antarctica.</div> |
398 | + >>> browser.open('https://launchpad.dev/ubuntu/+mirror/archive-mirror2') |
399 | + >>> browser.getLink("Change details").click() |
400 | + >>> print browser.title |
401 | + Edit mirror Archive-mirror2... |
402 | + >>> browser.getControl(name='field.country_dns_mirror').value = True |
403 | + >>> browser.getControl('Save').click() |
404 | + >>> print find_tags_by_class(browser.contents, 'message') |
405 | + [<p class="error message">There is 1 error.</p>, |
406 | + <div class="message">Antarctica already has a country DNS mirror set, please |
407 | + unset the country DNS mirror status of Davis Station before |
408 | + continuing.</div>] |
409 | + |
410 | +We can however set a country archive mirror for another country in the |
411 | +mean-time, just fine: |
412 | + |
413 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
414 | + >>> browser.open( |
415 | + ... 'https://launchpad.dev/ubuntu/+mirror/ubuntu.mirror.tudos.de-archive') |
416 | + >>> browser.getLink("Change details").click() |
417 | + >>> print browser.title |
418 | + Edit mirror Technische Universität Dresden... |
419 | + >>> browser.getControl(name='field.country_dns_mirror').value = True |
420 | + >>> browser.getControl('Save').click() |
421 | + >>> print find_tags_by_class(browser.contents, 'informational message')[0] |
422 | + <div class="informational message">The mirror Technische Universität |
423 | + Dresden has been set as the country DNS mirror for Germany.</div> |
424 | + |
425 | +Setting releases mirrors as country releases mirrors should not conflict with |
426 | +country archive mirrors settings: |
427 | + |
428 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
429 | + >>> browser.open( |
430 | + ... 'https://launchpad.dev/ubuntu/+mirror/mirror.mawson.antarctica.org-releases') |
431 | + >>> browser.getLink("Change details").click() |
432 | + >>> print browser.title |
433 | + Edit mirror Mawson Station... |
434 | + >>> browser.getControl(name='field.country_dns_mirror').value = True |
435 | + >>> browser.getControl('Save').click() |
436 | + >>> print find_tags_by_class(browser.contents, 'informational message')[0] |
437 | + <div class="informational message">The mirror Mawson Station has been set |
438 | + as the country DNS mirror for Antarctica.</div> |
439 | + |
440 | +Once a mirror has been set as a country mirror, it's content type or country |
441 | +may not be changed: |
442 | + |
443 | + >>> browser = setupBrowser(auth='Basic karl@canonical.com:test') |
444 | + >>> browser.open( |
445 | + ... 'https://launchpad.dev/ubuntu/+mirror/mirror.mawson.antarctica.org-releases') |
446 | + >>> browser.getLink("Change details").click() |
447 | + >>> print browser.title |
448 | + Edit mirror Mawson Station... |
449 | + >>> browser.getControl(name='field.content').value = ["ARCHIVE"] |
450 | + >>> browser.getControl('Save').click() |
451 | + >>> print find_tags_by_class(browser.contents, 'message') |
452 | + [<p class="error message">There is 1 error.</p>, |
453 | + <div class="message">Changing the mirror content type of country DNS |
454 | + mirrors is forbidden.</div>] |
455 | + >>> browser.open( |
456 | + ... 'https://launchpad.dev/ubuntu/+mirror/mirror.mawson.antarctica.org-releases') |
457 | + >>> browser.getLink("Change details").click() |
458 | + >>> print browser.title |
459 | + Edit mirror Mawson Station... |
460 | + >>> browser.getControl(name='field.country').value = ['82'] # Germany. |
461 | + >>> browser.getControl('Save').click() |
462 | + >>> print find_tags_by_class(browser.contents, 'message') |
463 | + [<p class="error message">There is 1 error.</p>, |
464 | + <div class="message">Changing the country of country DNS mirrors is |
465 | + forbidden.</div>] |
466 | + |
467 | |
468 | === Disabled mirrors === |
469 | |
470 | @@ -105,7 +256,7 @@ |
471 | 'http://launchpad.dev/ubuntu/+unofficialmirrors' |
472 | |
473 | >>> print_mirrors_by_countries(browser.contents) |
474 | - France: [(u'Invalid-mirror', u'http', u'2 Mbps', u'Last update unknown')] |
475 | + France: [(u'Invalid-mirror', u'', u'http', u'2 Mbps', u'Last update unknown')] |
476 | |
477 | == Pending-review mirrors == |
478 | |
479 | @@ -133,8 +284,8 @@ |
480 | >>> browser.open('http://launchpad.dev/ubuntu/+pendingreviewmirrors') |
481 | >>> print_mirrors_by_countries(browser.contents) |
482 | Afghanistan: |
483 | - [(u'Kabul LUG mirror', u'ftp', u'10 Gbps', |
484 | + [(u'Kabul LUG mirror', u'', u'ftp', u'10 Gbps', |
485 | u'Archive')] |
486 | United Kingdom: |
487 | - [(u'Random-releases-mirror', u'http', u'100 Mbps', |
488 | + [(u'Random-releases-mirror', u'', u'http', u'100 Mbps', |
489 | u'CD Image')] |
490 | |
491 | === modified file 'lib/lp/registry/templates/distributionmirror-index.pt' |
492 | --- lib/lp/registry/templates/distributionmirror-index.pt 2009-12-08 15:51:34 +0000 |
493 | +++ lib/lp/registry/templates/distributionmirror-index.pt 2010-01-05 15:14:20 +0000 |
494 | @@ -76,6 +76,15 @@ |
495 | </div> |
496 | </div> |
497 | </div> |
498 | + <div tal:condition="context/country_dns_mirror"> |
499 | + <div class="portlet"> |
500 | + <h2>Country DNS mirror</h2> |
501 | + <p> |
502 | + This mirror is the country DNS mirror for <span |
503 | + tal:content="context/country/name" />. |
504 | + </p> |
505 | + </div> |
506 | + </div> |
507 | |
508 | <div class="portlet" |
509 | id="last-probe" |
510 | |
511 | === modified file 'lib/lp/registry/templates/distributionmirror-macros.pt' |
512 | --- lib/lp/registry/templates/distributionmirror-macros.pt 2009-12-09 19:41:23 +0000 |
513 | +++ lib/lp/registry/templates/distributionmirror-macros.pt 2010-01-05 15:14:20 +0000 |
514 | @@ -19,6 +19,7 @@ |
515 | <tr class="highlighted"> |
516 | <th colspan="2" style="text-align: left" |
517 | tal:content="country_and_mirrors/country" /> |
518 | + <th align="right" /> |
519 | <th style="text-align: left" |
520 | tal:content="country_and_mirrors/throughput"/> |
521 | <th style="text-align: left" tal:condition="show_mirror_type"> |
522 | @@ -36,6 +37,10 @@ |
523 | <a tal:attributes="href mirror/fmt:url" |
524 | tal:content="mirror/title">Mirror Name</a> |
525 | </td> |
526 | + <td align="right"> |
527 | + <img tal:condition="mirror/country_dns_mirror" src="/@@/favourite-yes" |
528 | + title="Country DNS mirror" /> |
529 | + </td> |
530 | <td> |
531 | <a tal:condition="mirror/http_base_url" |
532 | tal:attributes="href mirror/http_base_url">http</a> |
533 | @@ -65,10 +70,11 @@ |
534 | |
535 | </tal:country_and_mirrors> |
536 | <tr class="highlighted"> |
537 | - <th colspan="5" style="text-align: left; font-weight: bold;">Total</th> |
538 | + <th colspan="6" style="text-align: left; font-weight: bold;">Total</th> |
539 | </tr> |
540 | <tr> |
541 | <td colspan="2" /> |
542 | + <td /> |
543 | <td style="text-align: left; font-weight: bold;" |
544 | tal:content="total_throughput" /> |
545 | <td tal:condition="show_mirror_type"></td> |
= Summary =
Launchpad should know which mirrors are set as official country mirrors (eg. gb.archive. ubuntu. com), so that we can track these easily on mirror listings.
This branch also includes a database change (patch- 2207-20- 0.sql) which adds a official_ country_ mirror column to distributionmirror. It also includes two constraints to ensure that there can not be more than one (archive|releases) mirror per country.
New mirrors have been added to current(-dev).sql for testing purposes too.
A mirror should only be eligible for country mirror status when:
1) it has been reviewed and set as an official mirror by an admin,
2) it has been probed for integrity,
3) it has an HTTP URL set.
4) there is no country mirror for that mirror type in the country.
Checks have been added to the code to ensure that these conditions are met.