Merge lp:~stevenk/launchpad/populate-branch-aag into lp:launchpad

Proposed by Steve Kowalik on 2012-06-27
Status: Merged
Approved by: William Grant on 2012-07-02
Approved revision: no longer in the source branch.
Merged at revision: 15532
Proposed branch: lp:~stevenk/launchpad/populate-branch-aag
Merge into: lp:launchpad
Diff against target: 155 lines (+87/-1)
3 files modified
database/schema/security.cfg (+2/-0)
lib/lp/scripts/garbo.py (+47/-0)
lib/lp/scripts/tests/test_garbo.py (+38/-1)
To merge this branch: bzr merge lp:~stevenk/launchpad/populate-branch-aag
Reviewer Review Type Date Requested Status
William Grant code 2012-06-27 Approve on 2012-07-02
Review via email: mp+112264@code.launchpad.net

Commit Message

Create a new garbo job to populate Branch.access_grants (via AccessArtifactGrants)

Description of the Change

Create a new garbo job to populate Branch.access_grants (via AccessArtifactGrants)

To post a comment you must log in.
William Grant (wgrant) :
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-06-26 14:23:03 +0000
3+++ database/schema/security.cfg 2012-07-02 08:29:22 +0000
4@@ -2197,6 +2197,8 @@
5
6 [garbo]
7 groups=script,read
8+public.accessartifact = SELECT, INSERT
9+public.accessartifactgrant = SELECT, INSERT
10 public.account = SELECT, DELETE
11 public.answercontact = SELECT, DELETE
12 public.branch = SELECT, UPDATE
13
14=== modified file 'lib/lp/scripts/garbo.py'
15--- lib/lp/scripts/garbo.py 2012-06-22 05:36:22 +0000
16+++ lib/lp/scripts/garbo.py 2012-07-02 08:29:22 +0000
17@@ -51,6 +51,7 @@
18 MAX_SAMPLE_SIZE,
19 )
20 from lp.code.interfaces.revision import IRevisionSet
21+from lp.code.model.branch import Branch
22 from lp.code.model.codeimportevent import CodeImportEvent
23 from lp.code.model.codeimportresult import CodeImportResult
24 from lp.code.model.revision import (
25@@ -58,6 +59,11 @@
26 RevisionCache,
27 )
28 from lp.hardwaredb.model.hwdb import HWSubmission
29+from lp.registry.enums import PRIVATE_INFORMATION_TYPES
30+from lp.registry.interfaces.accesspolicy import (
31+ IAccessArtifactGrantSource,
32+ IAccessArtifactSource,
33+ )
34 from lp.registry.model.person import Person
35 from lp.services.config import config
36 from lp.services.database import postgresql
37@@ -1137,6 +1143,46 @@
38 transaction.commit()
39
40
41+class PopulateBranchAccessArtifactGrant(TunableLoop):
42+
43+ maximum_chunk_size = 5000
44+
45+ def __init__(self, log, abort_time=None):
46+ super(PopulateBranchAccessArtifactGrant, self).__init__(
47+ log, abort_time)
48+ self.memcache_key = '%s:branch-populate-aag' % config.instance_name
49+ watermark = getUtility(IMemcacheClient).get(self.memcache_key)
50+ self.start_at = watermark or 0
51+
52+ def findBranches(self):
53+ return IMasterStore(Branch).find(
54+ Branch,
55+ Branch.information_type.is_in(PRIVATE_INFORMATION_TYPES),
56+ Branch.id >= self.start_at).order_by(Branch.id)
57+
58+ def isDone(self):
59+ return self.findBranches().is_empty()
60+
61+ def __call__(self, chunk_size):
62+ branches = list(self.findBranches()[:chunk_size])
63+ artifacts = getUtility(IAccessArtifactSource).ensure(branches)
64+ branch_to_artifact = dict(
65+ (artifact.branch_id, artifact) for artifact in artifacts)
66+ grants = []
67+ for branch in branches:
68+ artifact = branch_to_artifact[branch.id]
69+ grants.extend(
70+ [(artifact, branchsub.person, branchsub.subscribed_by)
71+ for branchsub in branch.subscriptions])
72+ getUtility(IAccessArtifactGrantSource).grant(grants)
73+ self.start_at = branches[-1].id + 1
74+ result = getUtility(IMemcacheClient).set(
75+ self.memcache_key, self.start_at)
76+ if not result:
77+ self.log.warning('Failed to set start_at in memcache.')
78+ transaction.commit()
79+
80+
81 class BaseDatabaseGarbageCollector(LaunchpadCronScript):
82 """Abstract base class to run a collection of TunableLoops."""
83 script_name = None # Script name for locking and database user. Override.
84@@ -1392,6 +1438,7 @@
85 DuplicateSessionPruner,
86 BugHeatUpdater,
87 BugTaskFlattener,
88+ PopulateBranchAccessArtifactGrant,
89 ]
90 experimental_tunable_loops = []
91
92
93=== modified file 'lib/lp/scripts/tests/test_garbo.py'
94--- lib/lp/scripts/tests/test_garbo.py 2012-06-22 05:36:22 +0000
95+++ lib/lp/scripts/tests/test_garbo.py 2012-07-02 08:29:22 +0000
96@@ -47,7 +47,11 @@
97 BranchFormat,
98 RepositoryFormat,
99 )
100-from lp.code.enums import CodeImportResultStatus
101+from lp.code.enums import (
102+ BranchSubscriptionNotificationLevel,
103+ CodeImportResultStatus,
104+ CodeReviewNotificationLevel,
105+ )
106 from lp.code.interfaces.codeimportevent import ICodeImportEventSet
107 from lp.code.model.branchjob import (
108 BranchJob,
109@@ -55,6 +59,7 @@
110 )
111 from lp.code.model.codeimportevent import CodeImportEvent
112 from lp.code.model.codeimportresult import CodeImportResult
113+from lp.registry.enums import InformationType
114 from lp.registry.interfaces.distribution import IDistributionSet
115 from lp.registry.interfaces.person import IPersonSet
116 from lp.scripts.garbo import (
117@@ -1149,6 +1154,38 @@
118 self.runHourly()
119 self.assertEqual((task.id,), get_flat())
120
121+ def test_PopulateBranchAccessArtifactGrant(self):
122+ # Branches without a access_policy have one set by the job.
123+ with dbuser('testadmin'):
124+ branch = self.factory.makeBranch()
125+
126+ def get_access_grants():
127+ return IMasterStore(BugTask).execute(
128+ 'SELECT access_grants FROM branch WHERE id = ?',
129+ (branch.id,)).get_one()[0]
130+
131+ # The branch is public, so running the garbo job will have no effect.
132+ self.runHourly()
133+ self.assertIs(None, get_access_grants())
134+
135+ with dbuser('testadmin'):
136+ branch.transitionToInformationType(
137+ InformationType.USERDATA, branch.owner, verify_policy=False)
138+
139+ # Now the branch is USERDATA, it will have no explicit grants.
140+ self.assertEqual([], get_access_grants())
141+
142+ with dbuser('testadmin'):
143+ subscriber = self.factory.makePerson()
144+ branch.subscribe(
145+ subscriber, BranchSubscriptionNotificationLevel.NOEMAIL,
146+ None, CodeReviewNotificationLevel.NOEMAIL, branch.owner)
147+
148+ # The subscriber has been added.
149+ self.runHourly()
150+ self.assertContentEqual(
151+ [branch.owner.id, subscriber.id], get_access_grants())
152+
153
154 class TestGarboTasks(TestCaseWithFactory):
155 layer = LaunchpadZopelessLayer