Merge lp:~jelmer/launchpad/cronjob into lp:launchpad

Proposed by Jelmer Vernooij on 2010-11-11
Status: Merged
Approved by: Gavin Panella on 2010-11-11
Approved revision: no longer in the source branch.
Merged at revision: 11923
Proposed branch: lp:~jelmer/launchpad/cronjob
Merge into: lp:launchpad
Diff against target: 261 lines (+172/-4)
7 files modified
configs/development/launchpad-lazr.conf (+4/-0)
cronscripts/sync-packages.py (+25/-0)
database/schema/security.cfg (+43/-0)
lib/canonical/config/schema-lazr.conf (+12/-0)
lib/lp/registry/browser/distroseries.py (+2/-1)
lib/lp/soyuz/model/syncpackagejob.py (+5/-2)
lib/lp/soyuz/tests/test_syncpackagejob.py (+81/-1)
To merge this branch: bzr merge lp:~jelmer/launchpad/cronjob
Reviewer Review Type Date Requested Status
Gavin Panella (community) 2010-11-11 Approve on 2010-11-11
Review via email: mp+40629@code.launchpad.net

Commit Message

[r=allenap][ui=none][no-qa] Add sync_packages cronjob and SyncPackageJob.run implementation.

Description of the Change

This adds a cronjob for synchronizing packages between archives, and adds the body of the SyncPackageJob.run.

To post a comment you must log in.
Jelmer Vernooij (jelmer) wrote :

This branch is lint clean.

tests: ./bin/test lp.soyuz.tests.test_syncpackagejob

Gavin Panella (allenap) wrote :

Looks good. I have several comments, but only [3] is likely to be of
importance, maybe [2] also.

[1]

+oops_prefix: IDSJ

Does this need to be configured for other environments too? Or is that
in production-configs?

[2]

+error_dir: /var/tmp/soyuz.test

Any idea how this pans out with parallel testing?

[3]

=== modified file 'database/schema/security.cfg'

This is targeted to devel. Because of the changes to security.cfg, you
might be better off landing this to db-devel, because you'll need to
prepare an extra script to grant these permissions on qastaging and
production otherwise.

[4]

=== added file 'cronscripts/sync_packages.py'

Scripts named with hyphens outnumber those with underscores 49 to 7.

Consider doing the right thing here ;)

Or tell me to f*** off :)

[5]

+ vars = job.getOopsVars()

vars is a builtin, so consider renaming this to avoid confusion.

[6]

Consider running utilities/format-new-and-modified-imports -r submit:
in your branch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'configs/development/launchpad-lazr.conf'
2--- configs/development/launchpad-lazr.conf 2010-10-25 20:42:59 +0000
3+++ configs/development/launchpad-lazr.conf 2010-11-12 11:27:13 +0000
4@@ -137,6 +137,10 @@
5 oops_prefix: IDSJ
6 error_dir: /var/tmp/soyuz.test
7
8+[sync_packages]
9+oops_prefix: SPJ
10+error_dir: /var/tmp/soyuz.test
11+
12 [launchpad]
13 enable_test_openid_provider: True
14 openid_provider_vhost: testopenid
15
16=== added file 'cronscripts/sync-packages.py'
17--- cronscripts/sync-packages.py 1970-01-01 00:00:00 +0000
18+++ cronscripts/sync-packages.py 2010-11-12 11:27:13 +0000
19@@ -0,0 +1,25 @@
20+#!/usr/bin/python -S
21+#
22+# Copyright 2010 Canonical Ltd. This software is licensed under the
23+# GNU Affero General Public License version 3 (see the file LICENSE).
24+
25+"""Synchronize packages."""
26+
27+__metaclass__ = type
28+
29+import _pythonpath
30+
31+from lp.services.job.runner import JobCronScript
32+from lp.soyuz.interfaces.distributionjob import ISyncPackageJobSource
33+
34+
35+class RunSyncPackageJob(JobCronScript):
36+ """Run SyncPackageJob jobs."""
37+
38+ config_name = 'sync_packages'
39+ source_interface = ISyncPackageJobSource
40+
41+
42+if __name__ == '__main__':
43+ script = RunSyncPackageJob()
44+ script.lock_and_run()
45
46=== modified file 'database/schema/security.cfg'
47--- database/schema/security.cfg 2010-11-09 10:26:19 +0000
48+++ database/schema/security.cfg 2010-11-12 11:27:13 +0000
49@@ -968,6 +968,49 @@
50 public.sourcepackagepublishinghistory = SELECT, INSERT
51 public.sourcepackagerelease = SELECT
52
53+[sync_packages]
54+type=user
55+groups=script
56+public.archive = SELECT
57+public.archivepermission = SELECT, INSERT
58+public.binarypackagebuild = SELECT, INSERT
59+public.binarypackagefile = SELECT, INSERT
60+public.binarypackagename = SELECT
61+public.binarypackagepublishinghistory = SELECT, INSERT
62+public.binarypackagerelease = SELECT
63+public.buildfarmjob = SELECT, INSERT
64+public.buildpackagejob = SELECT, INSERT, UPDATE, DELETE
65+public.buildqueue = SELECT, INSERT, UPDATE
66+public.component = SELECT
67+public.componentselection = SELECT, INSERT
68+public.distribution = SELECT
69+public.distributionjob = SELECT
70+public.distroarchseries = SELECT, INSERT
71+public.distroseries = SELECT, UPDATE
72+public.flatpackagesetinclusion = SELECT, INSERT
73+public.gpgkey = SELECT
74+public.job = SELECT, INSERT, UPDATE, DELETE
75+public.libraryfilealias = SELECT, INSERT, UPDATE, DELETE
76+public.libraryfilecontent = SELECT, INSERT
77+public.packagebuild = SELECT, INSERT
78+public.packageset = SELECT, INSERT
79+public.packagesetgroup = SELECT, INSERT
80+public.packagesetinclusion = SELECT, INSERT
81+public.packagesetsources = SELECT, INSERT
82+public.packageupload = SELECT
83+public.packaging = SELECT, INSERT
84+public.person = SELECT
85+public.pocketchroot = SELECT
86+public.processor = SELECT
87+public.processorfamily = SELECT
88+public.section = SELECT
89+public.sectionselection = SELECT, INSERT
90+public.sourcepackageformatselection = SELECT, INSERT
91+public.sourcepackagename = SELECT
92+public.sourcepackagepublishinghistory = SELECT, INSERT
93+public.sourcepackagerelease = SELECT
94+public.sourcepackagereleasefile = SELECT, INSERT, UPDATE
95+
96 [write]
97 type=group
98 # Full access except for tables that are exclusively updated by
99
100=== modified file 'lib/canonical/config/schema-lazr.conf'
101--- lib/canonical/config/schema-lazr.conf 2010-11-08 05:22:26 +0000
102+++ lib/canonical/config/schema-lazr.conf 2010-11-12 11:27:13 +0000
103@@ -940,6 +940,18 @@
104 # See [error_reports].
105 copy_to_zlog: false
106
107+[sync_packages]
108+dbuser: sync_packages
109+
110+# See [error_reports].
111+error_dir: none
112+
113+# See [error_reports].
114+oops_prefix: none
115+
116+# See [error_reports].
117+copy_to_zlog: false
118+
119 [karmacacheupdater]
120 # The database user which will be used by this process.
121 # datatype: string
122
123=== modified file 'lib/lp/registry/browser/distroseries.py'
124--- lib/lp/registry/browser/distroseries.py 2010-10-06 18:53:53 +0000
125+++ lib/lp/registry/browser/distroseries.py 2010-11-12 11:27:13 +0000
126@@ -77,7 +77,8 @@
127 )
128 from lp.registry.interfaces.distroseries import IDistroSeries
129 from lp.registry.interfaces.distroseriesdifference import (
130- IDistroSeriesDifferenceSource)
131+ IDistroSeriesDifferenceSource,
132+ )
133 from lp.registry.interfaces.series import SeriesStatus
134 from lp.services.features import getFeatureFlag
135 from lp.services.propertycache import cachedproperty
136
137=== modified file 'lib/lp/soyuz/model/syncpackagejob.py'
138--- lib/lp/soyuz/model/syncpackagejob.py 2010-11-05 12:03:15 +0000
139+++ lib/lp/soyuz/model/syncpackagejob.py 2010-11-12 11:27:13 +0000
140@@ -17,7 +17,6 @@
141 IMasterStore,
142 IStore,
143 )
144-
145 from lp.registry.interfaces.pocket import PackagePublishingPocket
146 from lp.soyuz.interfaces.archive import IArchiveSet
147 from lp.soyuz.interfaces.distributionjob import (
148@@ -98,4 +97,8 @@
149
150 def run(self):
151 """See `IRunnableJob`."""
152- raise NotImplementedError(self.run)
153+ self.target_archive.syncSource(
154+ self.source_package_name, self.source_package_version,
155+ self.source_archive, to_pocket=str(self.pocket),
156+ to_series=self.distroseries.name,
157+ include_binaries=self.include_binaries)
158
159=== modified file 'lib/lp/soyuz/tests/test_syncpackagejob.py'
160--- lib/lp/soyuz/tests/test_syncpackagejob.py 2010-11-04 13:37:23 +0000
161+++ lib/lp/soyuz/tests/test_syncpackagejob.py 2010-11-12 11:27:13 +0000
162@@ -1,14 +1,26 @@
163 # Copyright 2010 Canonical Ltd. This software is licensed under the
164 # GNU Affero General Public License version 3 (see the file LICENSE).
165
166+"""Tests for sync package jobs."""
167+
168+import os
169+import subprocess
170+import sys
171+
172+import transaction
173 from zope.component import getUtility
174+from zope.security.proxy import removeSecurityProxy
175
176+from canonical.config import config
177 from canonical.testing import LaunchpadZopelessLayer
178+from lp.registry.errors import NoSuchSourcePackageName
179+from lp.registry.interfaces.pocket import PackagePublishingPocket
180 from lp.soyuz.interfaces.distributionjob import (
181 ISyncPackageJob,
182 ISyncPackageJobSource,
183 )
184-from lp.registry.interfaces.pocket import PackagePublishingPocket
185+from lp.soyuz.interfaces.publishing import PackagePublishingStatus
186+from lp.soyuz.tests.test_publishing import SoyuzTestPublisher
187 from lp.testing import TestCaseWithFactory
188
189
190@@ -45,3 +57,71 @@
191 PackagePublishingPocket.RELEASE,
192 "foo", "1.0-1", include_binaries=False)
193 self.assertContentEqual([job], source.getActiveJobs(archive2))
194+
195+ def test_cronscript(self):
196+ # The cron script runs without problems.
197+ script = os.path.join(
198+ config.root, 'cronscripts', 'sync-packages.py')
199+ args = [sys.executable, script, '-v']
200+ process = subprocess.Popen(
201+ args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
202+ stdout, stderr = process.communicate()
203+ self.assertEqual(process.returncode, 0)
204+
205+ def test_run_unknown_package(self):
206+ # A job properly records failure.
207+ distroseries = self.factory.makeDistroSeries()
208+ archive1 = self.factory.makeArchive(distroseries.distribution)
209+ archive2 = self.factory.makeArchive(distroseries.distribution)
210+ source = getUtility(ISyncPackageJobSource)
211+ job = source.create(archive1, archive2, distroseries,
212+ PackagePublishingPocket.RELEASE,
213+ "foo", "1.0-1", include_binaries=False)
214+ self.assertRaises(NoSuchSourcePackageName, job.run)
215+
216+ def test_run(self):
217+ # A proper test run synchronizes packages.
218+ publisher = SoyuzTestPublisher()
219+ publisher.prepareBreezyAutotest()
220+ distroseries = publisher.breezy_autotest
221+
222+ archive1 = self.factory.makeArchive(distroseries.distribution)
223+ archive2 = self.factory.makeArchive(distroseries.distribution)
224+
225+ publisher.getPubBinaries(
226+ distroseries=distroseries, binaryname="libc",
227+ version="2.8-1",
228+ status=PackagePublishingStatus.PUBLISHED,
229+ archive=archive1)
230+
231+ source = getUtility(ISyncPackageJobSource)
232+ job = source.create(archive1, archive2, distroseries,
233+ PackagePublishingPocket.RELEASE,
234+ "libc", "2.8-1", include_binaries=False)
235+ # Make sure everything hits the database, switching db users
236+ # aborts.
237+ transaction.commit()
238+ self.layer.switchDbUser('sync_packages')
239+ job.run()
240+
241+ published_sources = archive2.getPublishedSources()
242+ self.assertEquals(1, published_sources.count())
243+ spr = published_sources[0].sourcepackagerelease
244+ self.assertEquals("libc", spr.name)
245+ self.assertEquals("2.8-1", spr.version)
246+
247+ def test_getOopsVars(self):
248+ distroseries = self.factory.makeDistroSeries()
249+ archive1 = self.factory.makeArchive(distroseries.distribution)
250+ archive2 = self.factory.makeArchive(distroseries.distribution)
251+ source = getUtility(ISyncPackageJobSource)
252+ job = source.create(archive1, archive2, distroseries,
253+ PackagePublishingPocket.RELEASE,
254+ "foo", "1.0-1", include_binaries=False)
255+ oops_vars = job.getOopsVars()
256+ naked_job = removeSecurityProxy(job)
257+ self.assertIn(
258+ ('distribution_id', distroseries.distribution.id), oops_vars)
259+ self.assertIn(('distroseries_id', distroseries.id), oops_vars)
260+ self.assertIn(
261+ ('distribution_job_id', naked_job.context.id), oops_vars)