Merge lp:~jtv/launchpad/bug-836743 into lp:launchpad

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: William Grant
Approved revision: no longer in the source branch.
Merged at revision: 13823
Proposed branch: lp:~jtv/launchpad/bug-836743
Merge into: lp:launchpad
Diff against target: 131 lines (+55/-9)
4 files modified
lib/lp/archivepublisher/config.py (+3/-1)
lib/lp/archivepublisher/scripts/publish_ftpmaster.py (+23/-8)
lib/lp/archivepublisher/tests/test_config.py (+19/-0)
lib/lp/archivepublisher/tests/test_publish_ftpmaster.py (+10/-0)
To merge this branch: bzr merge lp:~jtv/launchpad/bug-836743
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+73267@code.launchpad.net

Commit message

[r=wgrant][bug=836743] Make publish_ftpmaster resistant to configless archives.

Description of the change

= Summary =

The publish-ftpmaster script broke when it encountered a distribution archive without a publisher config. Could be a bit of a handicap when iterating over all derived distributions, including any that haven't had their configuration set up.

== Proposed fix ==

Have getPubConfig return None for archives that have no configuration in the database. Have publish_ftpmaster ignore distros without archive configs.

== Pre-implementation notes ==

This came up while trying out the publisher's --all-derived option on dogfood. Apparently the publisher config needs to be set up in the UI; distros that don't have it set up yet evidently aren't ready for publishing.

== Implementation details ==

You'll note that I made getConfigs() skip missing configs _per archive_, but main() check for and skip missing configs _per distro_. A distro can have multiple archives.

But the publisher config in the database is keyed off the distro's main archive. So there seems to be no middle ground between "distro without configs" and "distro with configs," unless it's a distro without archives.

== Tests ==

{{{
./bin/test -vvc lp.archivepublisher.tests.test_publish_ftpmaster
}}}

== Demo and Q/A ==

Run "cronscripts/publish-ftpmaster.py --all-derived" on dogfood. It should get further than the previous attempt, which broke after a few seconds (i.e. ZCML processing, sigh) during getConfigs very early in the script.

= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/archivepublisher/scripts/publish_ftpmaster.py
  lib/lp/archivepublisher/tests/test_config.py
  lib/lp/archivepublisher/config.py
  lib/lp/archivepublisher/tests/test_publish_ftpmaster.py

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/archivepublisher/config.py'
--- lib/lp/archivepublisher/config.py 2011-03-30 04:51:49 +0000
+++ lib/lp/archivepublisher/config.py 2011-08-29 17:16:29 +0000
@@ -13,8 +13,8 @@
13from canonical.config import config13from canonical.config import config
14from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet14from lp.archivepublisher.interfaces.publisherconfig import IPublisherConfigSet
15from lp.soyuz.enums import (15from lp.soyuz.enums import (
16 archive_suffixes,
16 ArchivePurpose,17 ArchivePurpose,
17 archive_suffixes,
18 )18 )
1919
2020
@@ -32,6 +32,8 @@
32 ppa_config = config.personalpackagearchive32 ppa_config = config.personalpackagearchive
33 db_pubconf = getUtility(33 db_pubconf = getUtility(
34 IPublisherConfigSet).getByDistribution(archive.distribution)34 IPublisherConfigSet).getByDistribution(archive.distribution)
35 if db_pubconf is None:
36 return None
3537
36 pubconf.temproot = os.path.join(38 pubconf.temproot = os.path.join(
37 db_pubconf.root_dir, '%s-temp' % archive.distribution.name)39 db_pubconf.root_dir, '%s-temp' % archive.distribution.name)
3840
=== modified file 'lib/lp/archivepublisher/scripts/publish_ftpmaster.py'
--- lib/lp/archivepublisher/scripts/publish_ftpmaster.py 2011-08-22 08:03:13 +0000
+++ lib/lp/archivepublisher/scripts/publish_ftpmaster.py 2011-08-29 17:16:29 +0000
@@ -148,6 +148,21 @@
148 return None148 return None
149149
150150
151def map_distro_pubconfigs(distro):
152 """Return dict mapping archive purpose for distro's pub configs.
153
154 :param distro: `Distribution` to get publisher configs for.
155 :return: Dict mapping archive purposes to publisher configs, insofar as
156 they have publisher configs.
157 """
158 candidates = [
159 (archive.purpose, getPubConfig(archive))
160 for archive in get_publishable_archives(distro)]
161 return dict(
162 (purpose, config)
163 for purpose, config in candidates if config is not None)
164
165
151class PublishFTPMaster(LaunchpadCronScript):166class PublishFTPMaster(LaunchpadCronScript):
152 """Publish a distro (update).167 """Publish a distro (update).
153168
@@ -241,9 +256,7 @@
241 So: getConfigs[distro][purpose] gives you a config.256 So: getConfigs[distro][purpose] gives you a config.
242 """257 """
243 return dict(258 return dict(
244 (distro, dict(259 (distro, map_distro_pubconfigs(distro))
245 (archive.purpose, getPubConfig(archive))
246 for archive in get_publishable_archives(distro)))
247 for distro in self.distributions)260 for distro in self.distributions)
248261
249 def locateIndexesMarker(self, distribution, suite):262 def locateIndexesMarker(self, distribution, suite):
@@ -536,9 +549,10 @@
536 """Publish the distro's complete uploads."""549 """Publish the distro's complete uploads."""
537 self.logger.debug("Full publication. This may take some time.")550 self.logger.debug("Full publication. This may take some time.")
538 for archive in get_publishable_archives(distribution):551 for archive in get_publishable_archives(distribution):
539 # This, for the main archive, is where the script spends552 if archive.purpose in self.configs[distribution]:
540 # most of its time.553 # This, for the main archive, is where the script spends
541 self.publishDistroArchive(distribution, archive)554 # most of its time.
555 self.publishDistroArchive(distribution, archive)
542556
543 def publish(self, distribution, security_only=False):557 def publish(self, distribution, security_only=False):
544 """Do the main publishing work.558 """Do the main publishing work.
@@ -622,5 +636,6 @@
622 self.setUpDirs()636 self.setUpDirs()
623637
624 for distribution in self.distributions:638 for distribution in self.distributions:
625 self.processDistro(distribution)639 if len(self.configs[distribution]) > 0:
626 self.txn.commit()640 self.processDistro(distribution)
641 self.txn.commit()
627642
=== added file 'lib/lp/archivepublisher/tests/test_config.py'
--- lib/lp/archivepublisher/tests/test_config.py 1970-01-01 00:00:00 +0000
+++ lib/lp/archivepublisher/tests/test_config.py 2011-08-29 17:16:29 +0000
@@ -0,0 +1,19 @@
1# Copyright 2011 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Test publisher configs handling."""
5
6__metaclass__ = type
7
8from canonical.testing.layers import ZopelessDatabaseLayer
9from lp.archivepublisher.config import getPubConfig
10from lp.testing import TestCaseWithFactory
11
12
13class TestGetPubConfig(TestCaseWithFactory):
14
15 layer = ZopelessDatabaseLayer
16
17 def test_getPubConfig_returns_None_if_no_publisherconfig_found(self):
18 archive = self.factory.makeDistribution(no_pubconf=True).main_archive
19 self.assertEqual(None, getPubConfig(archive))
020
=== modified file 'lib/lp/archivepublisher/tests/test_publish_ftpmaster.py'
--- lib/lp/archivepublisher/tests/test_publish_ftpmaster.py 2011-08-19 02:34:11 +0000
+++ lib/lp/archivepublisher/tests/test_publish_ftpmaster.py 2011-08-29 17:16:29 +0000
@@ -310,10 +310,20 @@
310 script.setUp()310 script.setUp()
311 self.assertEqual([distro], script.getConfigs().keys())311 self.assertEqual([distro], script.getConfigs().keys())
312312
313 def test_getConfigs_skips_configless_distros(self):
314 distro = self.factory.makeDistribution(no_pubconf=True)
315 script = self.makeScript(distro)
316 script.setUp()
317 self.assertEqual({}, script.getConfigs()[distro])
318
313 def test_script_is_happy_with_no_publications(self):319 def test_script_is_happy_with_no_publications(self):
314 distro = self.makeDistroWithPublishDirectory()320 distro = self.makeDistroWithPublishDirectory()
315 self.makeScript(distro).main()321 self.makeScript(distro).main()
316322
323 def test_script_is_happy_with_no_pubconfigs(self):
324 distro = self.factory.makeDistribution(no_pubconf=True)
325 self.makeScript(distro).main()
326
317 def test_produces_listings(self):327 def test_produces_listings(self):
318 distro = self.makeDistroWithPublishDirectory()328 distro = self.makeDistroWithPublishDirectory()
319 self.makeScript(distro).main()329 self.makeScript(distro).main()