Merge lp:~stevenk/launchpad/accesspolicy-garbo into lp:launchpad

Proposed by Steve Kowalik on 2012-03-05
Status: Merged
Approved by: Steve Kowalik on 2012-03-05
Approved revision: no longer in the source branch.
Merged at revision: 14901
Proposed branch: lp:~stevenk/launchpad/accesspolicy-garbo
Merge into: lp:launchpad
Diff against target: 179 lines (+96/-2)
3 files modified
database/schema/security.cfg (+1/-0)
lib/lp/scripts/garbo.py (+72/-1)
lib/lp/scripts/tests/test_garbo.py (+23/-1)
To merge this branch: bzr merge lp:~stevenk/launchpad/accesspolicy-garbo
Reviewer Review Type Date Requested Status
Ian Booth (community) code 2012-03-05 Approve on 2012-03-05
Review via email: mp+95834@code.launchpad.net

Commit Message

[r=wallyworld][bug=946851] Add two garbo jobs that add two AccessPolicyTypes for each product and distribution.

Description of the Change

Add two garbo jobs that add two AccessPolicyTypes for each product and distribution.

To post a comment you must log in.
Ian Booth (wallyworld) wrote :

Nice. We should ensure the garbo job has run to completion before allowing people to make changes via the ui. The ui back end can cope with whatever is in the model, even if it is "incomplete", but other tools/scripts may not be able to.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'database/schema/security.cfg'
2--- database/schema/security.cfg 2012-03-02 02:51:37 +0000
3+++ database/schema/security.cfg 2012-03-05 04:37:18 +0000
4@@ -2132,6 +2132,7 @@
5
6 [garbo]
7 groups=script,read
8+public.accesspolicy = SELECT, INSERT
9 public.account = SELECT, DELETE
10 public.answercontact = SELECT, DELETE
11 public.branch = SELECT, UPDATE
12
13=== modified file 'lib/lp/scripts/garbo.py'
14--- lib/lp/scripts/garbo.py 2012-03-02 18:01:12 +0000
15+++ lib/lp/scripts/garbo.py 2012-03-05 04:37:18 +0000
16@@ -13,6 +13,7 @@
17 datetime,
18 timedelta,
19 )
20+import itertools
21 import logging
22 import multiprocessing
23 import os
24@@ -26,7 +27,12 @@
25 import iso8601
26 from psycopg2 import IntegrityError
27 import pytz
28-from storm.expr import In
29+from storm.expr import (
30+ Exists,
31+ In,
32+ Not,
33+ Select,
34+ )
35 from storm.locals import (
36 Max,
37 Min,
38@@ -57,7 +63,12 @@
39 RevisionCache,
40 )
41 from lp.hardwaredb.model.hwdb import HWSubmission
42+from lp.registry.enums import AccessPolicyType
43+from lp.registry.interfaces.accesspolicy import IAccessPolicySource
44+from lp.registry.model.accesspolicy import AccessPolicy
45+from lp.registry.model.distribution import Distribution
46 from lp.registry.model.person import Person
47+from lp.registry.model.product import Product
48 from lp.services.config import config
49 from lp.services.database import postgresql
50 from lp.services.database.constants import UTC_NOW
51@@ -990,6 +1001,64 @@
52 transaction.commit()
53
54
55+class AccessPolicyDistributionAddition(TunableLoop):
56+ """A `TunableLoop` to add AccessPolicy for all distributions."""
57+
58+ maximum_chunk_size = 5000
59+
60+ def __init__(self, log, abort_time=None):
61+ super(AccessPolicyDistributionAddition, self).__init__(
62+ log, abort_time)
63+ self.transaction = transaction
64+ self.store = IMasterStore(Distribution)
65+
66+ def findDistributions(self):
67+ return self.store.find(
68+ Distribution,
69+ Not(Exists(
70+ Select(AccessPolicy.id,
71+ tables=[AccessPolicy], where=[
72+ AccessPolicy.distribution_id == Distribution.id]))))
73+
74+ def isDone(self):
75+ return self.findDistributions().is_empty()
76+
77+ def __call__(self, chunk_size):
78+ policies = itertools.product(
79+ self.findDistributions()[:chunk_size],
80+ (AccessPolicyType.USERDATA, AccessPolicyType.EMBARGOEDSECURITY))
81+ getUtility(IAccessPolicySource).create(policies)
82+ self.transaction.commit()
83+
84+
85+class AccessPolicyProductAddition(TunableLoop):
86+ """A `TunableLoop` to add AccessPolicy for all products."""
87+
88+ maximum_chunk_size = 5000
89+
90+ def __init__(self, log, abort_time=None):
91+ super(AccessPolicyProductAddition, self).__init__(log, abort_time)
92+ self.transaction = transaction
93+ self.store = IMasterStore(Product)
94+
95+ def findProducts(self):
96+ return self.store.find(
97+ Product,
98+ Not(Exists(
99+ Select(AccessPolicy.id, tables=[AccessPolicy], where=[
100+ AccessPolicy.product_id == Product.id]))))
101+
102+ def isDone(self):
103+ return self.findProducts().is_empty()
104+
105+ def __call__(self, chunk_size):
106+ policies = itertools.product(
107+ self.findProducts()[:chunk_size],
108+ (AccessPolicyType.USERDATA, AccessPolicyType.EMBARGOEDSECURITY))
109+ getUtility(IAccessPolicySource).create(policies)
110+ self.transaction.commit()
111+
112+
113 class SpecificationWorkitemMigrator(TunableLoop):
114 """Migrate work-items from Specification.whiteboard to
115 SpecificationWorkItem.
116@@ -1315,6 +1384,8 @@
117 UnusedSessionPruner,
118 DuplicateSessionPruner,
119 BugHeatUpdater,
120+ AccessPolicyDistributionAddition,
121+ AccessPolicyProductAddition,
122 ]
123 experimental_tunable_loops = []
124
125
126=== modified file 'lib/lp/scripts/tests/test_garbo.py'
127--- lib/lp/scripts/tests/test_garbo.py 2012-03-02 18:01:12 +0000
128+++ lib/lp/scripts/tests/test_garbo.py 2012-03-05 04:37:18 +0000
129@@ -54,6 +54,8 @@
130 )
131 from lp.code.model.codeimportevent import CodeImportEvent
132 from lp.code.model.codeimportresult import CodeImportResult
133+from lp.registry.enums import AccessPolicyType
134+from lp.registry.interfaces.accesspolicy import IAccessPolicySource
135 from lp.registry.interfaces.person import IPersonSet
136 from lp.scripts.garbo import (
137 AntiqueSessionPruner,
138@@ -136,6 +138,7 @@
139 "cronscripts/garbo-hourly.py", ["-q"], expect_returncode=0)
140 self.failIf(out.strip(), "Output to stdout: %s" % out)
141 self.failIf(err.strip(), "Output to stderr: %s" % err)
142+ DatabaseLayer.force_dirty_database()
143
144
145 class BulkFoo(Storm):
146@@ -1018,6 +1021,26 @@
147 self.runHourly()
148 self.assertNotEqual(old_update, bug.heat_last_updated)
149
150+ def test_AccessPolicyDistributionAddition(self):
151+ switch_dbuser('testadmin')
152+ distribution = self.factory.makeDistribution()
153+ transaction.commit()
154+ self.runHourly()
155+ ap = getUtility(IAccessPolicySource).findByPillar((distribution,))
156+ expected = [
157+ AccessPolicyType.USERDATA, AccessPolicyType.EMBARGOEDSECURITY]
158+ self.assertContentEqual(expected, [policy.type for policy in ap])
159+
160+ def test_AccessPolicyProductAddition(self):
161+ switch_dbuser('testadmin')
162+ product = self.factory.makeProduct()
163+ transaction.commit()
164+ self.runHourly()
165+ ap = getUtility(IAccessPolicySource).findByPillar((product,))
166+ expected = [
167+ AccessPolicyType.USERDATA, AccessPolicyType.EMBARGOEDSECURITY]
168+ self.assertContentEqual(expected, [policy.type for policy in ap])
169+
170 def test_SpecificationWorkitemMigrator_not_enabled_by_default(self):
171 self.assertFalse(getFeatureFlag('garbo.workitem_migrator.enabled'))
172 switch_dbuser('testadmin')
173@@ -1085,7 +1108,6 @@
174 self.assertEqual(0, spec.work_items.count())
175
176
177-
178 class TestGarboTasks(TestCaseWithFactory):
179 layer = LaunchpadZopelessLayer
180