Merge lp:~stub/launchpad/garbo into lp:launchpad/db-devel
- garbo
- Merge into db-devel
Proposed by
Stuart Bishop
Status: | Merged | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Stuart Bishop | ||||||||||||
Approved revision: | no longer in the source branch. | ||||||||||||
Merged at revision: | not available | ||||||||||||
Proposed branch: | lp:~stub/launchpad/garbo | ||||||||||||
Merge into: | lp:launchpad/db-devel | ||||||||||||
Diff against target: | 1206 lines | ||||||||||||
To merge this branch: | bzr merge lp:~stub/launchpad/garbo | ||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Paul Hummer (community) | code | Approve | |
Review via email: mp+4834@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Stuart Bishop (stub) wrote : | # |
Revision history for this message
Paul Hummer (rockstar) wrote : | # |
Obviously, I can't comment on the database stuff, but the scripts themselves appear sound and well tested.
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'cronscripts/garbo-daily.py' | |||
2 | --- cronscripts/garbo-daily.py 1970-01-01 00:00:00 +0000 | |||
3 | +++ cronscripts/garbo-daily.py 2009-03-25 11:41:03 +0000 | |||
4 | @@ -0,0 +1,19 @@ | |||
5 | 1 | #!/usr/bin/python2.4 | ||
6 | 2 | # Copyright 2009 Canonical Ltd. All rights reserved. | ||
7 | 3 | |||
8 | 4 | """Database garbage collector. | ||
9 | 5 | |||
10 | 6 | Remove or archive unwanted data. Detect, warn and possibly repair data | ||
11 | 7 | corruption. | ||
12 | 8 | """ | ||
13 | 9 | |||
14 | 10 | __metaclass__ = type | ||
15 | 11 | __all__ = [] | ||
16 | 12 | |||
17 | 13 | import _pythonpath | ||
18 | 14 | from canonical.launchpad.scripts.garbo import DailyDatabaseGarbageCollector | ||
19 | 15 | |||
20 | 16 | if __name__ == '__main__': | ||
21 | 17 | script = DailyDatabaseGarbageCollector() | ||
22 | 18 | script.lock_and_run() | ||
23 | 19 | |||
24 | 0 | 20 | ||
25 | === added file 'cronscripts/garbo-hourly.py' | |||
26 | --- cronscripts/garbo-hourly.py 1970-01-01 00:00:00 +0000 | |||
27 | +++ cronscripts/garbo-hourly.py 2009-03-25 11:41:03 +0000 | |||
28 | @@ -0,0 +1,19 @@ | |||
29 | 1 | #!/usr/bin/python2.4 | ||
30 | 2 | # Copyright 2009 Canonical Ltd. All rights reserved. | ||
31 | 3 | |||
32 | 4 | """Database garbage collector. | ||
33 | 5 | |||
34 | 6 | Remove or archive unwanted data. Detect, warn and possibly repair data | ||
35 | 7 | corruption. | ||
36 | 8 | """ | ||
37 | 9 | |||
38 | 10 | __metaclass__ = type | ||
39 | 11 | __all__ = [] | ||
40 | 12 | |||
41 | 13 | import _pythonpath | ||
42 | 14 | from canonical.launchpad.scripts.garbo import HourlyDatabaseGarbageCollector | ||
43 | 15 | |||
44 | 16 | if __name__ == '__main__': | ||
45 | 17 | script = HourlyDatabaseGarbageCollector() | ||
46 | 18 | script.lock_and_run() | ||
47 | 19 | |||
48 | 0 | 20 | ||
49 | === added file 'database/schema/patch-2109-42-0.sql' | |||
50 | --- database/schema/patch-2109-42-0.sql 1970-01-01 00:00:00 +0000 | |||
51 | +++ database/schema/patch-2109-42-0.sql 2009-03-25 11:41:03 +0000 | |||
52 | @@ -0,0 +1,8 @@ | |||
53 | 1 | SET client_min_messages=ERROR; | ||
54 | 2 | |||
55 | 3 | ALTER TABLE OAuthNonce | ||
56 | 4 | ADD CONSTRAINT oauthnonce__access_token__fk | ||
57 | 5 | FOREIGN KEY (access_token) REFERENCES OAuthAccessToken; | ||
58 | 6 | |||
59 | 7 | INSERT INTO LaunchpadDatabaseRevision VALUES (2109, 42, 0); | ||
60 | 8 | |||
61 | 0 | 9 | ||
62 | === modified file 'database/schema/security.cfg' | |||
63 | --- database/schema/security.cfg 2009-03-24 22:08:20 +0000 | |||
64 | +++ database/schema/security.cfg 2009-03-25 11:41:03 +0000 | |||
65 | @@ -95,7 +95,7 @@ | |||
66 | 95 | [launchpad_main] | 95 | [launchpad_main] |
67 | 96 | # lpmain replication set access from the main Z3 application. | 96 | # lpmain replication set access from the main Z3 application. |
68 | 97 | type=user | 97 | type=user |
70 | 98 | groups=write | 98 | groups=write,script |
71 | 99 | public.account = SELECT | 99 | public.account = SELECT |
72 | 100 | public.announcement = SELECT, INSERT, UPDATE, DELETE | 100 | public.announcement = SELECT, INSERT, UPDATE, DELETE |
73 | 101 | public.answercontact = SELECT, INSERT, UPDATE, DELETE | 101 | public.answercontact = SELECT, INSERT, UPDATE, DELETE |
74 | @@ -232,7 +232,7 @@ | |||
75 | 232 | public.revisionauthor = SELECT, INSERT, UPDATE | 232 | public.revisionauthor = SELECT, INSERT, UPDATE |
76 | 233 | public.revisionnumber = SELECT, INSERT | 233 | public.revisionnumber = SELECT, INSERT |
77 | 234 | public.revisionparent = SELECT, INSERT | 234 | public.revisionparent = SELECT, INSERT |
79 | 235 | public.scriptactivity = SELECT, INSERT | 235 | public.scriptactivity = SELECT |
80 | 236 | public.shipitreport = SELECT, INSERT | 236 | public.shipitreport = SELECT, INSERT |
81 | 237 | public.shipitsurvey = SELECT, INSERT, UPDATE | 237 | public.shipitsurvey = SELECT, INSERT, UPDATE |
82 | 238 | public.shipitsurveyquestion = SELECT, INSERT | 238 | public.shipitsurveyquestion = SELECT, INSERT |
83 | @@ -278,8 +278,14 @@ | |||
84 | 278 | type=user | 278 | type=user |
85 | 279 | groups=launchpad_main | 279 | groups=launchpad_main |
86 | 280 | 280 | ||
87 | 281 | [script] | ||
88 | 282 | # Permissions required by all scripts. | ||
89 | 283 | type=group | ||
90 | 284 | public.scriptactivity = SELECT, INSERT | ||
91 | 285 | |||
92 | 281 | [statistician] | 286 | [statistician] |
93 | 282 | type=user | 287 | type=user |
94 | 288 | groups=script | ||
95 | 283 | public.archive = SELECT, UPDATE | 289 | public.archive = SELECT, UPDATE |
96 | 284 | public.archivearch = SELECT, UPDATE | 290 | public.archivearch = SELECT, UPDATE |
97 | 285 | public.binarypackagename = SELECT | 291 | public.binarypackagename = SELECT |
98 | @@ -308,7 +314,6 @@ | |||
99 | 308 | public.product = SELECT | 314 | public.product = SELECT |
100 | 309 | public.productseries = SELECT | 315 | public.productseries = SELECT |
101 | 310 | public.question = SELECT | 316 | public.question = SELECT |
102 | 311 | public.scriptactivity = SELECT, INSERT | ||
103 | 312 | public.sourcepackagename = SELECT | 317 | public.sourcepackagename = SELECT |
104 | 313 | public.sourcepackagepublishinghistory = SELECT | 318 | public.sourcepackagepublishinghistory = SELECT |
105 | 314 | public.sourcepackagerelease = SELECT | 319 | public.sourcepackagerelease = SELECT |
106 | @@ -329,6 +334,7 @@ | |||
107 | 329 | 334 | ||
108 | 330 | [librariangc] | 335 | [librariangc] |
109 | 331 | type=user | 336 | type=user |
110 | 337 | groups=script | ||
111 | 332 | public.libraryfilealias = SELECT, UPDATE, DELETE | 338 | public.libraryfilealias = SELECT, UPDATE, DELETE |
112 | 333 | public.libraryfilecontent = SELECT, UPDATE, DELETE | 339 | public.libraryfilecontent = SELECT, UPDATE, DELETE |
113 | 334 | # This user needs select on every table that references LibraryFileAlias | 340 | # This user needs select on every table that references LibraryFileAlias |
114 | @@ -358,7 +364,6 @@ | |||
115 | 358 | public.product = SELECT | 364 | public.product = SELECT |
116 | 359 | public.productreleasefile = SELECT | 365 | public.productreleasefile = SELECT |
117 | 360 | public.project = SELECT | 366 | public.project = SELECT |
118 | 361 | public.scriptactivity = SELECT, INSERT | ||
119 | 362 | public.shipitreport = SELECT | 367 | public.shipitreport = SELECT |
120 | 363 | public.shippingrun = SELECT | 368 | public.shippingrun = SELECT |
121 | 364 | public.sprint = SELECT | 369 | public.sprint = SELECT |
122 | @@ -369,6 +374,7 @@ | |||
123 | 369 | [productreleasefinder] | 374 | [productreleasefinder] |
124 | 370 | # Dyson release import script | 375 | # Dyson release import script |
125 | 371 | type=user | 376 | type=user |
126 | 377 | groups=script | ||
127 | 372 | public.product = SELECT | 378 | public.product = SELECT |
128 | 373 | public.productseries = SELECT | 379 | public.productseries = SELECT |
129 | 374 | public.productrelease = SELECT, INSERT, UPDATE | 380 | public.productrelease = SELECT, INSERT, UPDATE |
130 | @@ -378,26 +384,24 @@ | |||
131 | 378 | # Needed to write to the librarian | 384 | # Needed to write to the librarian |
132 | 379 | public.libraryfilealias = SELECT, INSERT | 385 | public.libraryfilealias = SELECT, INSERT |
133 | 380 | public.libraryfilecontent = SELECT, INSERT | 386 | public.libraryfilecontent = SELECT, INSERT |
134 | 381 | public.scriptactivity = SELECT, INSERT | ||
135 | 382 | 387 | ||
136 | 383 | [pofilestats] | 388 | [pofilestats] |
137 | 384 | # Translations POFile statistics verification/update script | 389 | # Translations POFile statistics verification/update script |
138 | 385 | type=user | 390 | type=user |
139 | 391 | groups=script | ||
140 | 386 | public.language = SELECT | 392 | public.language = SELECT |
141 | 387 | public.pofile = SELECT, UPDATE | 393 | public.pofile = SELECT, UPDATE |
142 | 388 | public.potemplate = SELECT | 394 | public.potemplate = SELECT |
143 | 389 | public.potmsgset = SELECT | 395 | public.potmsgset = SELECT |
144 | 390 | public.scriptactivity = SELECT, INSERT | ||
145 | 391 | public.translationmessage = SELECT | 396 | public.translationmessage = SELECT |
146 | 392 | public.translationtemplateitem = SELECT | 397 | public.translationtemplateitem = SELECT |
147 | 393 | 398 | ||
148 | 394 | [poimport] | 399 | [poimport] |
149 | 395 | # Rosetta import script | 400 | # Rosetta import script |
150 | 396 | type=user | 401 | type=user |
152 | 397 | groups=write | 402 | groups=write,script |
153 | 398 | public.account = SELECT, INSERT | 403 | public.account = SELECT, INSERT |
154 | 399 | public.customlanguagecode = SELECT | 404 | public.customlanguagecode = SELECT |
155 | 400 | public.scriptactivity = SELECT, INSERT | ||
156 | 401 | public.translationgroup = SELECT | 405 | public.translationgroup = SELECT |
157 | 402 | public.translationimportqueueentry = SELECT, DELETE | 406 | public.translationimportqueueentry = SELECT, DELETE |
158 | 403 | public.translationmessage = SELECT, INSERT, UPDATE | 407 | public.translationmessage = SELECT, INSERT, UPDATE |
159 | @@ -409,6 +413,7 @@ | |||
160 | 409 | [poexport] | 413 | [poexport] |
161 | 410 | # Rosetta export script | 414 | # Rosetta export script |
162 | 411 | type=user | 415 | type=user |
163 | 416 | groups=script | ||
164 | 412 | public.distribution = SELECT | 417 | public.distribution = SELECT |
165 | 413 | public.distroseries = SELECT | 418 | public.distroseries = SELECT |
166 | 414 | public.emailaddress = SELECT | 419 | public.emailaddress = SELECT |
167 | @@ -427,7 +432,6 @@ | |||
168 | 427 | public.potranslation = SELECT | 432 | public.potranslation = SELECT |
169 | 428 | public.product = SELECT | 433 | public.product = SELECT |
170 | 429 | public.productseries = SELECT | 434 | public.productseries = SELECT |
171 | 430 | public.scriptactivity = SELECT, INSERT | ||
172 | 431 | public.sourcepackagename = SELECT | 435 | public.sourcepackagename = SELECT |
173 | 432 | public.translationgroup = SELECT | 436 | public.translationgroup = SELECT |
174 | 433 | public.translationmessage = SELECT | 437 | public.translationmessage = SELECT |
175 | @@ -439,6 +443,7 @@ | |||
176 | 439 | [langpack] | 443 | [langpack] |
177 | 440 | # Language pack exporter script | 444 | # Language pack exporter script |
178 | 441 | type=user | 445 | type=user |
179 | 446 | groups=script | ||
180 | 442 | public.distribution = SELECT | 447 | public.distribution = SELECT |
181 | 443 | public.distroseries = SELECT, UPDATE | 448 | public.distroseries = SELECT, UPDATE |
182 | 444 | public.emailaddress = SELECT | 449 | public.emailaddress = SELECT |
183 | @@ -457,7 +462,6 @@ | |||
184 | 457 | public.potranslation = SELECT | 462 | public.potranslation = SELECT |
185 | 458 | public.product = SELECT | 463 | public.product = SELECT |
186 | 459 | public.productseries = SELECT | 464 | public.productseries = SELECT |
187 | 460 | public.scriptactivity = SELECT, INSERT | ||
188 | 461 | public.sourcepackagename = SELECT | 465 | public.sourcepackagename = SELECT |
189 | 462 | public.translationgroup = SELECT | 466 | public.translationgroup = SELECT |
190 | 463 | public.translationmessage = SELECT | 467 | public.translationmessage = SELECT |
191 | @@ -469,6 +473,7 @@ | |||
192 | 469 | [checkwatches] | 473 | [checkwatches] |
193 | 470 | # Malone bug watch script | 474 | # Malone bug watch script |
194 | 471 | type=user | 475 | type=user |
195 | 476 | groups=script | ||
196 | 472 | public.account = SELECT, INSERT | 477 | public.account = SELECT, INSERT |
197 | 473 | public.accountpassword = SELECT, INSERT | 478 | public.accountpassword = SELECT, INSERT |
198 | 474 | public.answercontact = SELECT | 479 | public.answercontact = SELECT |
199 | @@ -506,7 +511,6 @@ | |||
200 | 506 | public.questionbug = SELECT | 511 | public.questionbug = SELECT |
201 | 507 | public.question = SELECT | 512 | public.question = SELECT |
202 | 508 | public.questionsubscription = SELECT | 513 | public.questionsubscription = SELECT |
203 | 509 | public.scriptactivity = SELECT, INSERT | ||
204 | 510 | public.sourcepackagename = SELECT | 514 | public.sourcepackagename = SELECT |
205 | 511 | public.structuralsubscription = SELECT | 515 | public.structuralsubscription = SELECT |
206 | 512 | public.teammembership = SELECT | 516 | public.teammembership = SELECT |
207 | @@ -532,7 +536,7 @@ | |||
208 | 532 | 536 | ||
209 | 533 | [branchscanner] | 537 | [branchscanner] |
210 | 534 | type=user | 538 | type=user |
212 | 535 | groups=write | 539 | groups=write, script |
213 | 536 | public.account = SELECT, INSERT | 540 | public.account = SELECT, INSERT |
214 | 537 | public.accountpassword = SELECT, INSERT | 541 | public.accountpassword = SELECT, INSERT |
215 | 538 | public.branch = SELECT, UPDATE | 542 | public.branch = SELECT, UPDATE |
216 | @@ -556,7 +560,6 @@ | |||
217 | 556 | public.revisionauthor = SELECT, INSERT, UPDATE | 560 | public.revisionauthor = SELECT, INSERT, UPDATE |
218 | 557 | public.revisionparent = SELECT, INSERT | 561 | public.revisionparent = SELECT, INSERT |
219 | 558 | public.revisionproperty = SELECT, INSERT | 562 | public.revisionproperty = SELECT, INSERT |
220 | 559 | public.scriptactivity = SELECT, INSERT | ||
221 | 560 | public.sourcepackagename = SELECT | 563 | public.sourcepackagename = SELECT |
222 | 561 | public.staticdiff = SELECT, INSERT, DELETE | 564 | public.staticdiff = SELECT, INSERT, DELETE |
223 | 562 | public.validpersoncache = SELECT | 565 | public.validpersoncache = SELECT |
224 | @@ -564,6 +567,7 @@ | |||
225 | 564 | 567 | ||
226 | 565 | [targetnamecacheupdater] | 568 | [targetnamecacheupdater] |
227 | 566 | type=user | 569 | type=user |
228 | 570 | groups=script | ||
229 | 567 | public.bugtask = SELECT, UPDATE | 571 | public.bugtask = SELECT, UPDATE |
230 | 568 | public.product = SELECT | 572 | public.product = SELECT |
231 | 569 | public.productseries = SELECT | 573 | public.productseries = SELECT |
232 | @@ -572,10 +576,10 @@ | |||
233 | 572 | public.sourcepackagename = SELECT | 576 | public.sourcepackagename = SELECT |
234 | 573 | public.binarypackagename = SELECT | 577 | public.binarypackagename = SELECT |
235 | 574 | public.potemplate = SELECT, UPDATE | 578 | public.potemplate = SELECT, UPDATE |
236 | 575 | public.scriptactivity = SELECT, INSERT | ||
237 | 576 | 579 | ||
238 | 577 | [distributionmirror] | 580 | [distributionmirror] |
239 | 578 | type=user | 581 | type=user |
240 | 582 | groups=script | ||
241 | 579 | public.archive = SELECT | 583 | public.archive = SELECT |
242 | 580 | public.archivearch = SELECT | 584 | public.archivearch = SELECT |
243 | 581 | public.binarypackagefile = SELECT | 585 | public.binarypackagefile = SELECT |
244 | @@ -597,7 +601,6 @@ | |||
245 | 597 | public.mirrorproberecord = SELECT, INSERT | 601 | public.mirrorproberecord = SELECT, INSERT |
246 | 598 | public.person = SELECT | 602 | public.person = SELECT |
247 | 599 | public.processorfamily = SELECT | 603 | public.processorfamily = SELECT |
248 | 600 | public.scriptactivity = SELECT, INSERT | ||
249 | 601 | public.securesourcepackagepublishinghistory = SELECT | 604 | public.securesourcepackagepublishinghistory = SELECT |
250 | 602 | public.securebinarypackagepublishinghistory = SELECT | 605 | public.securebinarypackagepublishinghistory = SELECT |
251 | 603 | public.sourcepackagerelease = SELECT | 606 | public.sourcepackagerelease = SELECT |
252 | @@ -608,15 +611,16 @@ | |||
253 | 608 | [teammembership] | 611 | [teammembership] |
254 | 609 | # Update the TeamMembership table setting expired members | 612 | # Update the TeamMembership table setting expired members |
255 | 610 | type=user | 613 | type=user |
256 | 614 | groups=script | ||
257 | 611 | public.teammembership = SELECT, UPDATE | 615 | public.teammembership = SELECT, UPDATE |
258 | 612 | public.teamparticipation = SELECT, DELETE | 616 | public.teamparticipation = SELECT, DELETE |
259 | 613 | public.person = SELECT | 617 | public.person = SELECT |
260 | 614 | public.emailaddress = SELECT | 618 | public.emailaddress = SELECT |
261 | 615 | public.scriptactivity = SELECT, INSERT | ||
262 | 616 | 619 | ||
263 | 617 | [karma] | 620 | [karma] |
264 | 618 | # Update the KarmaCache table | 621 | # Update the KarmaCache table |
265 | 619 | type=user | 622 | type=user |
266 | 623 | groups=script | ||
267 | 620 | public.karmacache = SELECT, INSERT, UPDATE, DELETE | 624 | public.karmacache = SELECT, INSERT, UPDATE, DELETE |
268 | 621 | public.karma = SELECT | 625 | public.karma = SELECT |
269 | 622 | public.karmacategory = SELECT | 626 | public.karmacategory = SELECT |
270 | @@ -627,11 +631,11 @@ | |||
271 | 627 | public.product = SELECT | 631 | public.product = SELECT |
272 | 628 | public.validpersoncache = SELECT | 632 | public.validpersoncache = SELECT |
273 | 629 | public.validpersonorteamcache = SELECT | 633 | public.validpersonorteamcache = SELECT |
274 | 630 | public.scriptactivity = SELECT, INSERT | ||
275 | 631 | 634 | ||
276 | 632 | [revisionkarma] | 635 | [revisionkarma] |
277 | 633 | # Allocate karma for revisions. | 636 | # Allocate karma for revisions. |
278 | 634 | type=user | 637 | type=user |
279 | 638 | groups=script | ||
280 | 635 | public.branch = SELECT | 639 | public.branch = SELECT |
281 | 636 | public.branchrevision = SELECT | 640 | public.branchrevision = SELECT |
282 | 637 | public.karma = SELECT, INSERT | 641 | public.karma = SELECT, INSERT |
283 | @@ -642,20 +646,19 @@ | |||
284 | 642 | public.productseries = SELECT | 646 | public.productseries = SELECT |
285 | 643 | public.revision = SELECT, UPDATE | 647 | public.revision = SELECT, UPDATE |
286 | 644 | public.revisionauthor = SELECT | 648 | public.revisionauthor = SELECT |
287 | 645 | public.scriptactivity = SELECT, INSERT | ||
288 | 646 | public.validpersoncache = SELECT | 649 | public.validpersoncache = SELECT |
289 | 647 | 650 | ||
290 | 648 | [cve] | 651 | [cve] |
291 | 649 | type=user | 652 | type=user |
292 | 653 | groups=script | ||
293 | 650 | public.cve = SELECT, INSERT, UPDATE | 654 | public.cve = SELECT, INSERT, UPDATE |
294 | 651 | public.cvereference = SELECT, INSERT, UPDATE, DELETE | 655 | public.cvereference = SELECT, INSERT, UPDATE, DELETE |
295 | 652 | public.scriptactivity = SELECT, INSERT | ||
296 | 653 | 656 | ||
297 | 654 | 657 | ||
298 | 655 | [gina] | 658 | [gina] |
299 | 656 | # Unpack sourcepackages and extract metadata | 659 | # Unpack sourcepackages and extract metadata |
300 | 657 | type=user | 660 | type=user |
302 | 658 | groups=write | 661 | groups=write,script |
303 | 659 | public.account = SELECT, INSERT | 662 | public.account = SELECT, INSERT |
304 | 660 | public.accountpassword = SELECT, INSERT | 663 | public.accountpassword = SELECT, INSERT |
305 | 661 | public.archive = SELECT, UPDATE | 664 | public.archive = SELECT, UPDATE |
306 | @@ -663,14 +666,13 @@ | |||
307 | 663 | public.distribution = SELECT | 666 | public.distribution = SELECT |
308 | 664 | public.openidrpsummary = SELECT | 667 | public.openidrpsummary = SELECT |
309 | 665 | public.packagediff = SELECT, INSERT, UPDATE | 668 | public.packagediff = SELECT, INSERT, UPDATE |
310 | 666 | public.scriptactivity = SELECT, INSERT | ||
311 | 667 | public.securebinarypackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE | 669 | public.securebinarypackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE |
312 | 668 | public.securesourcepackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE | 670 | public.securesourcepackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE |
313 | 669 | 671 | ||
314 | 670 | [lucille] | 672 | [lucille] |
315 | 671 | # Soyuz archive publisher. | 673 | # Soyuz archive publisher. |
316 | 672 | type=user | 674 | type=user |
318 | 673 | groups=write | 675 | groups=write,script |
319 | 674 | public.archive = SELECT, UPDATE | 676 | public.archive = SELECT, UPDATE |
320 | 675 | public.archivearch = SELECT | 677 | public.archivearch = SELECT |
321 | 676 | public.archiveauthtoken = SELECT, UPDATE | 678 | public.archiveauthtoken = SELECT, UPDATE |
322 | @@ -679,7 +681,6 @@ | |||
323 | 679 | public.gpgkey = SELECT, INSERT, UPDATE | 681 | public.gpgkey = SELECT, INSERT, UPDATE |
324 | 680 | public.packagecopyrequest = SELECT, INSERT, UPDATE | 682 | public.packagecopyrequest = SELECT, INSERT, UPDATE |
325 | 681 | public.packagediff = SELECT, INSERT, UPDATE | 683 | public.packagediff = SELECT, INSERT, UPDATE |
326 | 682 | public.scriptactivity = SELECT, INSERT | ||
327 | 683 | public.securebinarypackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE | 684 | public.securebinarypackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE |
328 | 684 | public.securesourcepackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE | 685 | public.securesourcepackagepublishinghistory = SELECT, INSERT, UPDATE, DELETE |
329 | 685 | public.sourcepackagepublishinghistory = SELECT | 686 | public.sourcepackagepublishinghistory = SELECT |
330 | @@ -719,6 +720,7 @@ | |||
331 | 719 | 720 | ||
332 | 720 | [fiera] | 721 | [fiera] |
333 | 721 | type=user | 722 | type=user |
334 | 723 | groups=script | ||
335 | 722 | public.account = SELECT | 724 | public.account = SELECT |
336 | 723 | public.archive = SELECT, UPDATE | 725 | public.archive = SELECT, UPDATE |
337 | 724 | public.archivearch = SELECT, UPDATE | 726 | public.archivearch = SELECT, UPDATE |
338 | @@ -750,11 +752,11 @@ | |||
339 | 750 | public.person = SELECT | 752 | public.person = SELECT |
340 | 751 | public.emailaddress = SELECT | 753 | public.emailaddress = SELECT |
341 | 752 | public.teammembership = SELECT | 754 | public.teammembership = SELECT |
342 | 753 | public.scriptactivity = SELECT, INSERT | ||
343 | 754 | public.gpgkey = SELECT | 755 | public.gpgkey = SELECT |
344 | 755 | 756 | ||
345 | 756 | [sourcerer] | 757 | [sourcerer] |
346 | 757 | type=user | 758 | type=user |
347 | 759 | groups=script | ||
348 | 758 | public.archive = SELECT | 760 | public.archive = SELECT |
349 | 759 | public.archivearch = SELECT | 761 | public.archivearch = SELECT |
350 | 760 | public.branch = SELECT, INSERT, UPDATE | 762 | public.branch = SELECT, INSERT, UPDATE |
351 | @@ -779,7 +781,6 @@ | |||
352 | 779 | # To get stuff from the librarian | 781 | # To get stuff from the librarian |
353 | 780 | public.libraryfilealias = SELECT | 782 | public.libraryfilealias = SELECT |
354 | 781 | public.libraryfilecontent = SELECT | 783 | public.libraryfilecontent = SELECT |
355 | 782 | public.scriptactivity = SELECT, INSERT | ||
356 | 783 | 784 | ||
357 | 784 | [write] | 785 | [write] |
358 | 785 | type=group | 786 | type=group |
359 | @@ -884,6 +885,7 @@ | |||
360 | 884 | 885 | ||
361 | 885 | [shipit] | 886 | [shipit] |
362 | 886 | type=user | 887 | type=user |
363 | 888 | groups=script | ||
364 | 887 | public.account = SELECT | 889 | public.account = SELECT |
365 | 888 | public.continent = SELECT | 890 | public.continent = SELECT |
366 | 889 | public.country = SELECT | 891 | public.country = SELECT |
367 | @@ -893,7 +895,6 @@ | |||
368 | 893 | public.libraryfilecontent = SELECT, INSERT | 895 | public.libraryfilecontent = SELECT, INSERT |
369 | 894 | public.person = SELECT | 896 | public.person = SELECT |
370 | 895 | public.requestedcds = SELECT, INSERT, UPDATE | 897 | public.requestedcds = SELECT, INSERT, UPDATE |
371 | 896 | public.scriptactivity = SELECT, INSERT | ||
372 | 897 | public.shipitreport = SELECT, INSERT | 898 | public.shipitreport = SELECT, INSERT |
373 | 898 | public.shipment = SELECT, INSERT | 899 | public.shipment = SELECT, INSERT |
374 | 899 | public.shippingrequest = SELECT, UPDATE | 900 | public.shippingrequest = SELECT, UPDATE |
375 | @@ -905,17 +906,18 @@ | |||
376 | 905 | [standingupdater] | 906 | [standingupdater] |
377 | 906 | # For the personal standing updater cron script. | 907 | # For the personal standing updater cron script. |
378 | 907 | type=user | 908 | type=user |
379 | 909 | groups=script | ||
380 | 908 | public.emailaddress = SELECT | 910 | public.emailaddress = SELECT |
381 | 909 | public.mailinglist = SELECT | 911 | public.mailinglist = SELECT |
382 | 910 | public.message = SELECT | 912 | public.message = SELECT |
383 | 911 | public.messageapproval = SELECT | 913 | public.messageapproval = SELECT |
384 | 912 | public.person = SELECT, UPDATE | 914 | public.person = SELECT, UPDATE |
385 | 913 | public.scriptactivity = SELECT, INSERT | ||
386 | 914 | public.teamparticipation = SELECT | 915 | public.teamparticipation = SELECT |
387 | 915 | 916 | ||
388 | 916 | [answertracker] | 917 | [answertracker] |
389 | 917 | # User running expire-questions.py | 918 | # User running expire-questions.py |
390 | 918 | type=user | 919 | type=user |
391 | 920 | groups=script | ||
392 | 919 | public.account = SELECT, INSERT | 921 | public.account = SELECT, INSERT |
393 | 920 | public.accountpassword = SELECT, INSERT | 922 | public.accountpassword = SELECT, INSERT |
394 | 921 | public.answercontact = SELECT | 923 | public.answercontact = SELECT |
395 | @@ -935,7 +937,6 @@ | |||
396 | 935 | public.questionbug = SELECT | 937 | public.questionbug = SELECT |
397 | 936 | public.questionmessage = SELECT, INSERT | 938 | public.questionmessage = SELECT, INSERT |
398 | 937 | public.questionsubscription = SELECT | 939 | public.questionsubscription = SELECT |
399 | 938 | public.scriptactivity = SELECT, INSERT | ||
400 | 939 | public.sourcepackagename = SELECT | 940 | public.sourcepackagename = SELECT |
401 | 940 | public.teammembership = SELECT | 941 | public.teammembership = SELECT |
402 | 941 | public.validpersoncache = SELECT | 942 | public.validpersoncache = SELECT |
403 | @@ -943,6 +944,7 @@ | |||
404 | 943 | 944 | ||
405 | 944 | [uploader] | 945 | [uploader] |
406 | 945 | type=user | 946 | type=user |
407 | 947 | groups=script | ||
408 | 946 | # Everything is keyed off an archive | 948 | # Everything is keyed off an archive |
409 | 947 | public.archive = SELECT, INSERT, UPDATE | 949 | public.archive = SELECT, INSERT, UPDATE |
410 | 948 | public.archivearch = SELECT, INSERT, UPDATE | 950 | public.archivearch = SELECT, INSERT, UPDATE |
411 | @@ -1002,8 +1004,6 @@ | |||
412 | 1002 | public.packageuploadbuild = SELECT, INSERT | 1004 | public.packageuploadbuild = SELECT, INSERT |
413 | 1003 | public.packageuploadcustom = SELECT, INSERT | 1005 | public.packageuploadcustom = SELECT, INSERT |
414 | 1004 | 1006 | ||
415 | 1005 | public.scriptactivity = SELECT, INSERT | ||
416 | 1006 | |||
417 | 1007 | # For premature source-only publication | 1007 | # For premature source-only publication |
418 | 1008 | public.securesourcepackagepublishinghistory = SELECT, INSERT | 1008 | public.securesourcepackagepublishinghistory = SELECT, INSERT |
419 | 1009 | 1009 | ||
420 | @@ -1045,6 +1045,7 @@ | |||
421 | 1045 | 1045 | ||
422 | 1046 | [queued] | 1046 | [queued] |
423 | 1047 | type=user | 1047 | type=user |
424 | 1048 | groups=script | ||
425 | 1048 | # Announce handling | 1049 | # Announce handling |
426 | 1049 | public.account = SELECT, INSERT | 1050 | public.account = SELECT, INSERT |
427 | 1050 | public.person = SELECT, INSERT | 1051 | public.person = SELECT, INSERT |
428 | @@ -1097,8 +1098,6 @@ | |||
429 | 1097 | # rosetta auto imports | 1098 | # rosetta auto imports |
430 | 1098 | public.translationimportqueueentry = SELECT, INSERT, UPDATE | 1099 | public.translationimportqueueentry = SELECT, INSERT, UPDATE |
431 | 1099 | 1100 | ||
432 | 1100 | public.scriptactivity = SELECT, INSERT | ||
433 | 1101 | |||
434 | 1102 | # Closing bugs. | 1101 | # Closing bugs. |
435 | 1103 | public.bug = SELECT, UPDATE | 1102 | public.bug = SELECT, UPDATE |
436 | 1104 | public.bugactivity = SELECT, INSERT | 1103 | public.bugactivity = SELECT, INSERT |
437 | @@ -1135,10 +1134,10 @@ | |||
438 | 1135 | 1134 | ||
439 | 1136 | [ppad] | 1135 | [ppad] |
440 | 1137 | type=user | 1136 | type=user |
441 | 1137 | groups=script | ||
442 | 1138 | public.archive = SELECT | 1138 | public.archive = SELECT |
443 | 1139 | public.archivearch = SELECT | 1139 | public.archivearch = SELECT |
444 | 1140 | public.person = SELECT | 1140 | public.person = SELECT |
445 | 1141 | public.scriptactivity = SELECT, INSERT | ||
446 | 1142 | 1141 | ||
447 | 1143 | [session] | 1142 | [session] |
448 | 1144 | # This user doesn't have access to any tables in the main launchpad | 1143 | # This user doesn't have access to any tables in the main launchpad |
449 | @@ -1155,6 +1154,7 @@ | |||
450 | 1155 | # send-bug-notifications.py needs them. They should be removed | 1154 | # send-bug-notifications.py needs them. They should be removed |
451 | 1156 | # when bug 37456 is fixed. | 1155 | # when bug 37456 is fixed. |
452 | 1157 | type=user | 1156 | type=user |
453 | 1157 | groups=script | ||
454 | 1158 | public.account = SELECT | 1158 | public.account = SELECT |
455 | 1159 | public.archive = SELECT | 1159 | public.archive = SELECT |
456 | 1160 | public.archivearch = SELECT | 1160 | public.archivearch = SELECT |
457 | @@ -1187,7 +1187,6 @@ | |||
458 | 1187 | public.message = SELECT, INSERT | 1187 | public.message = SELECT, INSERT |
459 | 1188 | public.messagechunk = SELECT, INSERT | 1188 | public.messagechunk = SELECT, INSERT |
460 | 1189 | public.milestone = SELECT | 1189 | public.milestone = SELECT |
461 | 1190 | public.scriptactivity = SELECT, INSERT | ||
462 | 1191 | public.structuralsubscription = SELECT | 1190 | public.structuralsubscription = SELECT |
463 | 1192 | public.teammembership = SELECT | 1191 | public.teammembership = SELECT |
464 | 1193 | public.teamparticipation = SELECT | 1192 | public.teamparticipation = SELECT |
465 | @@ -1196,6 +1195,7 @@ | |||
466 | 1196 | 1195 | ||
467 | 1197 | [personnotification] | 1196 | [personnotification] |
468 | 1198 | type=user | 1197 | type=user |
469 | 1198 | groups=script | ||
470 | 1199 | public.personnotification = SELECT, UPDATE, DELETE | 1199 | public.personnotification = SELECT, UPDATE, DELETE |
471 | 1200 | public.person = SELECT | 1200 | public.person = SELECT |
472 | 1201 | public.emailaddress = SELECT | 1201 | public.emailaddress = SELECT |
473 | @@ -1203,7 +1203,6 @@ | |||
474 | 1203 | public.libraryfilecontent = SELECT | 1203 | public.libraryfilecontent = SELECT |
475 | 1204 | public.message = SELECT | 1204 | public.message = SELECT |
476 | 1205 | public.messagechunk = SELECT | 1205 | public.messagechunk = SELECT |
477 | 1206 | public.scriptactivity = SELECT, INSERT | ||
478 | 1207 | public.teammembership = SELECT | 1206 | public.teammembership = SELECT |
479 | 1208 | public.teamparticipation = SELECT | 1207 | public.teamparticipation = SELECT |
480 | 1209 | public.validpersoncache = SELECT | 1208 | public.validpersoncache = SELECT |
481 | @@ -1211,6 +1210,7 @@ | |||
482 | 1211 | 1210 | ||
483 | 1212 | [rosettaadmin] | 1211 | [rosettaadmin] |
484 | 1213 | type=user | 1212 | type=user |
485 | 1213 | groups=script | ||
486 | 1214 | public.customlanguagecode = SELECT, INSERT, UPDATE, DELETE | 1214 | public.customlanguagecode = SELECT, INSERT, UPDATE, DELETE |
487 | 1215 | public.distribution = SELECT | 1215 | public.distribution = SELECT |
488 | 1216 | public.distroseries = SELECT | 1216 | public.distroseries = SELECT |
489 | @@ -1225,7 +1225,6 @@ | |||
490 | 1225 | public.potranslation = SELECT | 1225 | public.potranslation = SELECT |
491 | 1226 | public.product = SELECT | 1226 | public.product = SELECT |
492 | 1227 | public.productseries = SELECT | 1227 | public.productseries = SELECT |
493 | 1228 | public.scriptactivity = SELECT, INSERT | ||
494 | 1229 | public.sourcepackagename = SELECT | 1228 | public.sourcepackagename = SELECT |
495 | 1230 | public.translationimportqueueentry = SELECT, INSERT, UPDATE, DELETE | 1229 | public.translationimportqueueentry = SELECT, INSERT, UPDATE, DELETE |
496 | 1231 | public.translationmessage = SELECT, INSERT, UPDATE, DELETE | 1230 | public.translationmessage = SELECT, INSERT, UPDATE, DELETE |
497 | @@ -1234,12 +1233,12 @@ | |||
498 | 1234 | 1233 | ||
499 | 1235 | [oopsprune] | 1234 | [oopsprune] |
500 | 1236 | type=user | 1235 | type=user |
501 | 1236 | groups=script | ||
502 | 1237 | public.bug = SELECT | 1237 | public.bug = SELECT |
503 | 1238 | public.bugtask = SELECT | 1238 | public.bugtask = SELECT |
504 | 1239 | public.message = SELECT | 1239 | public.message = SELECT |
505 | 1240 | public.messagechunk = SELECT | 1240 | public.messagechunk = SELECT |
506 | 1241 | public.question = SELECT | 1241 | public.question = SELECT |
507 | 1242 | public.scriptactivity = SELECT, INSERT | ||
508 | 1243 | 1242 | ||
509 | 1244 | [listteammembers] | 1243 | [listteammembers] |
510 | 1245 | type=user | 1244 | type=user |
511 | @@ -1260,7 +1259,7 @@ | |||
512 | 1260 | 1259 | ||
513 | 1261 | [processmail] | 1260 | [processmail] |
514 | 1262 | type=user | 1261 | type=user |
516 | 1263 | public.scriptactivity = SELECT, INSERT | 1262 | groups=script |
517 | 1264 | 1263 | ||
518 | 1265 | # Incoming emails are stored in the librarian | 1264 | # Incoming emails are stored in the librarian |
519 | 1266 | public.libraryfilealias = SELECT, INSERT | 1265 | public.libraryfilealias = SELECT, INSERT |
520 | @@ -1361,10 +1360,10 @@ | |||
521 | 1361 | [mlist-sync] | 1360 | [mlist-sync] |
522 | 1362 | # The mailing list sync user | 1361 | # The mailing list sync user |
523 | 1363 | type=user | 1362 | type=user |
524 | 1363 | groups=script | ||
525 | 1364 | public.mailinglist = SELECT | 1364 | public.mailinglist = SELECT |
526 | 1365 | public.person = SELECT | 1365 | public.person = SELECT |
527 | 1366 | public.emailaddress = SELECT, UPDATE | 1366 | public.emailaddress = SELECT, UPDATE |
528 | 1367 | public.scriptactivity = SELECT, INSERT | ||
529 | 1368 | 1367 | ||
530 | 1369 | [mlist-import] | 1368 | [mlist-import] |
531 | 1370 | # The mailing list import user | 1369 | # The mailing list import user |
532 | @@ -1379,6 +1378,7 @@ | |||
533 | 1379 | [hwdb-submission-processor] | 1378 | [hwdb-submission-processor] |
534 | 1380 | # The user that updates the HWDB with data from new submissions | 1379 | # The user that updates the HWDB with data from new submissions |
535 | 1381 | type=user | 1380 | type=user |
536 | 1381 | groups=script | ||
537 | 1382 | public.person = SELECT | 1382 | public.person = SELECT |
538 | 1383 | public.hwdevicedriverlink = SELECT, INSERT | 1383 | public.hwdevicedriverlink = SELECT, INSERT |
539 | 1384 | public.hwdevicenamevariant = SELECT, INSERT | 1384 | public.hwdevicenamevariant = SELECT, INSERT |
540 | @@ -1397,7 +1397,6 @@ | |||
541 | 1397 | public.hwvendorname = SELECT, INSERT | 1397 | public.hwvendorname = SELECT, INSERT |
542 | 1398 | public.libraryfilealias = SELECT | 1398 | public.libraryfilealias = SELECT |
543 | 1399 | public.libraryfilecontent = SELECT | 1399 | public.libraryfilecontent = SELECT |
544 | 1400 | public.scriptactivity = SELECT, INSERT | ||
545 | 1401 | public.teamparticipation = SELECT | 1400 | public.teamparticipation = SELECT |
546 | 1402 | 1401 | ||
547 | 1403 | [builddcontroller] | 1402 | [builddcontroller] |
548 | @@ -1409,6 +1408,7 @@ | |||
549 | 1409 | [binaryfile-expire] | 1408 | [binaryfile-expire] |
550 | 1410 | # The user that expires binary files from the librarian. | 1409 | # The user that expires binary files from the librarian. |
551 | 1411 | type=user | 1410 | type=user |
552 | 1411 | groups=script | ||
553 | 1412 | public.archive = SELECT | 1412 | public.archive = SELECT |
554 | 1413 | public.binarypackagefile = SELECT | 1413 | public.binarypackagefile = SELECT |
555 | 1414 | public.binarypackagepublishinghistory = SELECT | 1414 | public.binarypackagepublishinghistory = SELECT |
556 | @@ -1417,10 +1417,10 @@ | |||
557 | 1417 | public.person = SELECT | 1417 | public.person = SELECT |
558 | 1418 | public.libraryfilealias = SELECT, UPDATE | 1418 | public.libraryfilealias = SELECT, UPDATE |
559 | 1419 | public.securebinarypackagepublishinghistory = SELECT | 1419 | public.securebinarypackagepublishinghistory = SELECT |
560 | 1420 | public.scriptactivity = SELECT, UPDATE, INSERT, DELETE | ||
561 | 1421 | 1420 | ||
562 | 1422 | [create-merge-proposals] | 1421 | [create-merge-proposals] |
563 | 1423 | type=user | 1422 | type=user |
564 | 1423 | groups=script | ||
565 | 1424 | public.account = SELECT | 1424 | public.account = SELECT |
566 | 1425 | public.accountpassword = SELECT | 1425 | public.accountpassword = SELECT |
567 | 1426 | public.branch = SELECT, INSERT, UPDATE | 1426 | public.branch = SELECT, INSERT, UPDATE |
568 | @@ -1446,13 +1446,13 @@ | |||
569 | 1446 | public.product = SELECT | 1446 | public.product = SELECT |
570 | 1447 | public.productseries = SELECT | 1447 | public.productseries = SELECT |
571 | 1448 | public.project = SELECT | 1448 | public.project = SELECT |
572 | 1449 | public.scriptactivity = SELECT, INSERT | ||
573 | 1450 | public.staticdiff = SELECT, INSERT | 1449 | public.staticdiff = SELECT, INSERT |
574 | 1451 | public.teamparticipation = SELECT | 1450 | public.teamparticipation = SELECT |
575 | 1452 | public.validpersoncache = SELECT | 1451 | public.validpersoncache = SELECT |
576 | 1453 | 1452 | ||
577 | 1454 | [mp-creation-job] | 1453 | [mp-creation-job] |
578 | 1455 | type=user | 1454 | type=user |
579 | 1455 | groups=script | ||
580 | 1456 | public.account = SELECT | 1456 | public.account = SELECT |
581 | 1457 | public.accountpassword = SELECT | 1457 | public.accountpassword = SELECT |
582 | 1458 | public.branch = SELECT | 1458 | public.branch = SELECT |
583 | @@ -1475,7 +1475,6 @@ | |||
584 | 1475 | public.person = SELECT | 1475 | public.person = SELECT |
585 | 1476 | public.product = SELECT | 1476 | public.product = SELECT |
586 | 1477 | public.productseries = SELECT | 1477 | public.productseries = SELECT |
587 | 1478 | public.scriptactivity = SELECT, INSERT | ||
588 | 1479 | public.staticdiff = SELECT, INSERT | 1478 | public.staticdiff = SELECT, INSERT |
589 | 1480 | public.teammembership = SELECT | 1479 | public.teammembership = SELECT |
590 | 1481 | public.teamparticipation = SELECT | 1480 | public.teamparticipation = SELECT |
591 | @@ -1483,6 +1482,7 @@ | |||
592 | 1483 | 1482 | ||
593 | 1484 | [send-branch-mail] | 1483 | [send-branch-mail] |
594 | 1485 | type=user | 1484 | type=user |
595 | 1485 | groups=script | ||
596 | 1486 | public.account = SELECT | 1486 | public.account = SELECT |
597 | 1487 | public.accountpassword = SELECT | 1487 | public.accountpassword = SELECT |
598 | 1488 | public.branch = SELECT | 1488 | public.branch = SELECT |
599 | @@ -1507,7 +1507,6 @@ | |||
600 | 1507 | public.product = SELECT | 1507 | public.product = SELECT |
601 | 1508 | public.productseries = SELECT | 1508 | public.productseries = SELECT |
602 | 1509 | public.revision = SELECT | 1509 | public.revision = SELECT |
603 | 1510 | public.scriptactivity = SELECT, INSERT | ||
604 | 1511 | public.staticdiff = SELECT, INSERT | 1510 | public.staticdiff = SELECT, INSERT |
605 | 1512 | public.teammembership = SELECT | 1511 | public.teammembership = SELECT |
606 | 1513 | public.teamparticipation = SELECT | 1512 | public.teamparticipation = SELECT |
607 | @@ -1516,6 +1515,7 @@ | |||
608 | 1516 | [updateremoteproduct] | 1515 | [updateremoteproduct] |
609 | 1517 | # Updates Product.remote_product using bug watch information. | 1516 | # Updates Product.remote_product using bug watch information. |
610 | 1518 | type=user | 1517 | type=user |
611 | 1518 | groups=script | ||
612 | 1519 | public.account = SELECT, INSERT, UPDATE | 1519 | public.account = SELECT, INSERT, UPDATE |
613 | 1520 | public.person = SELECT, INSERT | 1520 | public.person = SELECT, INSERT |
614 | 1521 | public.product = SELECT, INSERT, UPDATE | 1521 | public.product = SELECT, INSERT, UPDATE |
615 | @@ -1537,14 +1537,13 @@ | |||
616 | 1537 | public.bugsubscription = SELECT, INSERT | 1537 | public.bugsubscription = SELECT, INSERT |
617 | 1538 | public.bugmessage = SELECT, INSERT | 1538 | public.bugmessage = SELECT, INSERT |
618 | 1539 | public.sourcepackagename = SELECT | 1539 | public.sourcepackagename = SELECT |
619 | 1540 | public.scriptactivity = SELECT, INSERT | ||
620 | 1541 | 1540 | ||
621 | 1542 | [updatesourceforgeremoteproduct] | 1541 | [updatesourceforgeremoteproduct] |
622 | 1543 | # Updates Product.remote_product using SourceForge project data. | 1542 | # Updates Product.remote_product using SourceForge project data. |
623 | 1544 | type=user | 1543 | type=user |
624 | 1544 | groups=script | ||
625 | 1545 | public.product = SELECT, UPDATE | 1545 | public.product = SELECT, UPDATE |
626 | 1546 | public.bugtracker = SELECT | 1546 | public.bugtracker = SELECT |
627 | 1547 | public.scriptactivity = SELECT, INSERT | ||
628 | 1548 | 1547 | ||
629 | 1549 | [weblogstats] | 1548 | [weblogstats] |
630 | 1550 | # For the script that parses our Apache/Squid logfiles and updates statistics | 1549 | # For the script that parses our Apache/Squid logfiles and updates statistics |
631 | @@ -1552,6 +1551,25 @@ | |||
632 | 1552 | public.libraryfilealias = SELECT | 1551 | public.libraryfilealias = SELECT |
633 | 1553 | public.libraryfiledownloadcount = SELECT, INSERT, UPDATE, DELETE | 1552 | public.libraryfiledownloadcount = SELECT, INSERT, UPDATE, DELETE |
634 | 1554 | 1553 | ||
635 | 1554 | [garbo] | ||
636 | 1555 | # garbo-hourly and garbo-daily script permissions. We define the | ||
637 | 1556 | # permissions here in this group instead of in the users, so tasks can | ||
638 | 1557 | # be shuffled around between the daily and hourly sections without | ||
639 | 1558 | # changing DB permissions. | ||
640 | 1559 | type=user | ||
641 | 1560 | groups=script | ||
642 | 1561 | public.codeimportresult = SELECT, DELETE | ||
643 | 1562 | public.oauthnonce = SELECT, DELETE | ||
644 | 1563 | public.openidnonce = SELECT, DELETE | ||
645 | 1564 | |||
646 | 1565 | [garbo-daily] | ||
647 | 1566 | type=user | ||
648 | 1567 | groups=garbo | ||
649 | 1568 | |||
650 | 1569 | [garbo-hourly] | ||
651 | 1570 | type=user | ||
652 | 1571 | groups=garbo | ||
653 | 1572 | |||
654 | 1555 | [generateppahtaccess] | 1573 | [generateppahtaccess] |
655 | 1556 | # For the generate_ppa_htaccess.py cronscript. | 1574 | # For the generate_ppa_htaccess.py cronscript. |
656 | 1557 | type=user | 1575 | type=user |
657 | 1558 | 1576 | ||
658 | === modified file 'database/schema/security.py' | |||
659 | --- database/schema/security.py 2009-03-23 19:32:14 +0000 | |||
660 | +++ database/schema/security.py 2009-03-25 11:41:03 +0000 | |||
661 | @@ -255,7 +255,8 @@ | |||
662 | 255 | obj.fullname, quote_identifier(options.owner) | 255 | obj.fullname, quote_identifier(options.owner) |
663 | 256 | )) | 256 | )) |
664 | 257 | 257 | ||
666 | 258 | # Revoke all privs | 258 | # Revoke all privs from known groups. Don't revoke anything for |
667 | 259 | # users or groups not defined in our security.cfg. | ||
668 | 259 | for section_name in config.sections(): | 260 | for section_name in config.sections(): |
669 | 260 | for obj in schema.values(): | 261 | for obj in schema.values(): |
670 | 261 | if obj.type == 'function': | 262 | if obj.type == 'function': |
671 | @@ -263,13 +264,16 @@ | |||
672 | 263 | else: | 264 | else: |
673 | 264 | t = 'TABLE' | 265 | t = 'TABLE' |
674 | 265 | 266 | ||
682 | 266 | cur.execute('REVOKE ALL ON %s %s FROM %s%s' % ( | 267 | roles = [quote_identifier(section_name)] |
683 | 267 | t, obj.fullname, g, quote_identifier(section_name) | 268 | if section_name != 'public': |
684 | 268 | )) | 269 | roles.append(quote_identifier(section_name + '_ro')) |
685 | 269 | if schema.has_key(obj.seqname): | 270 | for role in roles: |
686 | 270 | cur.execute('REVOKE ALL ON SEQUENCE %s FROM %s%s' % ( | 271 | cur.execute( |
687 | 271 | obj.seqname, g, quote_identifier(section_name), | 272 | 'REVOKE ALL ON %s %s FROM %s' % (t, obj.fullname, role)) |
688 | 272 | )) | 273 | if schema.has_key(obj.seqname): |
689 | 274 | cur.execute( | ||
690 | 275 | 'REVOKE ALL ON SEQUENCE %s FROM %s' | ||
691 | 276 | % (obj.seqname, role)) | ||
692 | 273 | 277 | ||
693 | 274 | # Set of all tables we have granted permissions on. After we have assigned | 278 | # Set of all tables we have granted permissions on. After we have assigned |
694 | 275 | # permissions, we can use this to determine what tables have been | 279 | # permissions, we can use this to determine what tables have been |
695 | 276 | 280 | ||
696 | === modified file 'importfascist.py' | |||
697 | --- importfascist.py 2009-03-23 19:32:14 +0000 | |||
698 | +++ importfascist.py 2009-03-25 11:41:03 +0000 | |||
699 | @@ -21,20 +21,20 @@ | |||
700 | 21 | 21 | ||
701 | 22 | # zope.testing.doctest: called as part of creating a DocTestSuite. | 22 | # zope.testing.doctest: called as part of creating a DocTestSuite. |
702 | 23 | permitted_database_imports = text_lines_to_set(""" | 23 | permitted_database_imports = text_lines_to_set(""" |
706 | 24 | zope.testing.doctest | 24 | canonical.archivepublisher.deathrow |
707 | 25 | canonical.librarian.db | 25 | canonical.archivepublisher.domination |
705 | 26 | canonical.doap.fileimporter | ||
708 | 27 | canonical.archivepublisher.ftparchive | 26 | canonical.archivepublisher.ftparchive |
709 | 28 | canonical.archivepublisher.publishing | 27 | canonical.archivepublisher.publishing |
710 | 29 | canonical.archivepublisher.domination | ||
711 | 30 | canonical.archivepublisher.deathrow | ||
712 | 31 | canonical.codehosting.inmemory | 28 | canonical.codehosting.inmemory |
713 | 32 | canonical.launchpad.browser.branchlisting | 29 | canonical.launchpad.browser.branchlisting |
714 | 33 | canonical.launchpad.feed.branch | 30 | canonical.launchpad.feed.branch |
715 | 31 | canonical.launchpad.scripts.garbo | ||
716 | 32 | canonical.launchpad.scripts.librarian_apache_log_parser | ||
717 | 33 | canonical.launchpad.validators.person | ||
718 | 34 | canonical.launchpad.vocabularies.dbobjects | 34 | canonical.launchpad.vocabularies.dbobjects |
719 | 35 | canonical.launchpad.validators.person | ||
720 | 36 | canonical.librarian.client | 35 | canonical.librarian.client |
722 | 37 | canonical.launchpad.scripts.librarian_apache_log_parser | 36 | canonical.librarian.db |
723 | 37 | zope.testing.doctest | ||
724 | 38 | """) | 38 | """) |
725 | 39 | # It's not worth creating a *Set utility for ParsedApacheLog, to be used only | 39 | # It's not worth creating a *Set utility for ParsedApacheLog, to be used only |
726 | 40 | # in librarian_apache_log_parser, so instead we allow that module to import | 40 | # in librarian_apache_log_parser, so instead we allow that module to import |
727 | 41 | 41 | ||
728 | === added file 'lib/canonical/launchpad/database/openidconsumer.py' | |||
729 | --- lib/canonical/launchpad/database/openidconsumer.py 1970-01-01 00:00:00 +0000 | |||
730 | +++ lib/canonical/launchpad/database/openidconsumer.py 2009-03-25 11:41:03 +0000 | |||
731 | @@ -0,0 +1,23 @@ | |||
732 | 1 | # Copyright 2009 Canonical Ltd. All rights reserved. | ||
733 | 2 | |||
734 | 3 | """OpenID Consumer related database classes.""" | ||
735 | 4 | |||
736 | 5 | __metaclass__ = type | ||
737 | 6 | __all__ = ['OpenIDNonce'] | ||
738 | 7 | |||
739 | 8 | from storm.locals import DateTime, Int, Storm, Unicode | ||
740 | 9 | |||
741 | 10 | class OpenIDNonce(Storm): | ||
742 | 11 | """An OpenIDNonce. | ||
743 | 12 | |||
744 | 13 | The table definition matches that required by the openid library, | ||
745 | 14 | so doesn't follow our standards. In particular, it doesn't have an | ||
746 | 15 | id column and the timestamp is an epoch time integer rather than a | ||
747 | 16 | datetime. | ||
748 | 17 | """ | ||
749 | 18 | __storm_table__ = "OpenIDNonce" | ||
750 | 19 | __storm_primary__ = "server_url", "timestamp", "salt" | ||
751 | 20 | |||
752 | 21 | server_url = Unicode() | ||
753 | 22 | timestamp = Int() | ||
754 | 23 | salt = Unicode() | ||
755 | 0 | 24 | ||
756 | === modified file 'lib/canonical/launchpad/doc/script-monitoring.txt' | |||
757 | --- lib/canonical/launchpad/doc/script-monitoring.txt 2008-12-01 18:05:42 +0000 | |||
758 | +++ lib/canonical/launchpad/doc/script-monitoring.txt 2009-03-25 11:41:03 +0000 | |||
759 | @@ -22,12 +22,13 @@ | |||
760 | 22 | >>> import sys | 22 | >>> import sys |
761 | 23 | >>> import tempfile | 23 | >>> import tempfile |
762 | 24 | >>> import pytz | 24 | >>> import pytz |
763 | 25 | >>> import transaction | ||
764 | 25 | >>> from zope.component import getUtility | 26 | >>> from zope.component import getUtility |
765 | 26 | >>> from canonical.database.sqlbase import ZopelessTransactionManager | ||
766 | 27 | >>> from canonical.launchpad.interfaces import IScriptActivitySet | 27 | >>> from canonical.launchpad.interfaces import IScriptActivitySet |
767 | 28 | >>> from canonical.testing.layers import LaunchpadZopelessLayer | ||
768 | 28 | 29 | ||
769 | 29 | >>> UTC = pytz.timezone('UTC') | 30 | >>> UTC = pytz.timezone('UTC') |
771 | 30 | >>> ztm = ZopelessTransactionManager._installed | 31 | >>> LaunchpadZopelessLayer.switchDbUser('garbo-daily') # A script db user |
772 | 31 | 32 | ||
773 | 32 | >>> activity = getUtility(IScriptActivitySet).recordSuccess( | 33 | >>> activity = getUtility(IScriptActivitySet).recordSuccess( |
774 | 33 | ... name='script-name', | 34 | ... name='script-name', |
775 | @@ -88,21 +89,21 @@ | |||
776 | 88 | ... raise RuntimeError('Some failure') | 89 | ... raise RuntimeError('Some failure') |
777 | 89 | ... | 90 | ... |
778 | 90 | ... if __name__ == '__main__': | 91 | ... if __name__ == '__main__': |
780 | 91 | ... script = TestScript('test-script') | 92 | ... script = TestScript('test-script', 'garbo-daily') |
781 | 92 | ... script.run() | 93 | ... script.run() |
782 | 93 | ... """) | 94 | ... """) |
783 | 94 | >>> script_file.flush() | 95 | >>> script_file.flush() |
784 | 95 | 96 | ||
785 | 96 | We'll now run this script, telling it to fail: | 97 | We'll now run this script, telling it to fail: |
786 | 97 | 98 | ||
788 | 98 | >>> ztm.commit() | 99 | >>> transaction.commit() |
789 | 99 | >>> env = dict(os.environ) | 100 | >>> env = dict(os.environ) |
790 | 100 | >>> env['LPCONFIG'] = 'testrunner' | 101 | >>> env['LPCONFIG'] = 'testrunner' |
791 | 101 | >>> proc = subprocess.Popen([sys.executable, script_file.name, 'fail'], | 102 | >>> proc = subprocess.Popen([sys.executable, script_file.name, 'fail'], |
792 | 102 | ... env=env, stdin=subprocess.PIPE, | 103 | ... env=env, stdin=subprocess.PIPE, |
793 | 103 | ... stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 104 | ... stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
794 | 104 | >>> (out, err) = proc.communicate() | 105 | >>> (out, err) = proc.communicate() |
796 | 105 | >>> ztm.abort() | 106 | >>> transaction.abort() |
797 | 106 | 107 | ||
798 | 107 | The process failed: | 108 | The process failed: |
799 | 108 | 109 | ||
800 | @@ -120,7 +121,7 @@ | |||
801 | 120 | ... env=env, stdin=subprocess.PIPE, | 121 | ... env=env, stdin=subprocess.PIPE, |
802 | 121 | ... stdout=subprocess.PIPE, stderr=subprocess.PIPE) | 122 | ... stdout=subprocess.PIPE, stderr=subprocess.PIPE) |
803 | 122 | >>> (out, err) = proc.communicate() | 123 | >>> (out, err) = proc.communicate() |
805 | 123 | >>> ztm.abort() | 124 | >>> transaction.abort() |
806 | 124 | 125 | ||
807 | 125 | >>> print proc.returncode | 126 | >>> print proc.returncode |
808 | 126 | 0 | 127 | 0 |
809 | 127 | 128 | ||
810 | === modified file 'lib/canonical/launchpad/scripts/base.py' | |||
811 | --- lib/canonical/launchpad/scripts/base.py 2008-10-21 11:30:50 +0000 | |||
812 | +++ lib/canonical/launchpad/scripts/base.py 2009-03-25 11:41:03 +0000 | |||
813 | @@ -70,7 +70,8 @@ | |||
814 | 70 | What you get: | 70 | What you get: |
815 | 71 | - self.logger | 71 | - self.logger |
816 | 72 | - self.txn | 72 | - self.txn |
818 | 73 | - self.options | 73 | - self.parser (the OptionParser) |
819 | 74 | - self.options (the parsed options) | ||
820 | 74 | 75 | ||
821 | 75 | "Give me convenience or give me death." | 76 | "Give me convenience or give me death." |
822 | 76 | """ | 77 | """ |
823 | 77 | 78 | ||
824 | === added file 'lib/canonical/launchpad/scripts/garbo.py' | |||
825 | --- lib/canonical/launchpad/scripts/garbo.py 1970-01-01 00:00:00 +0000 | |||
826 | +++ lib/canonical/launchpad/scripts/garbo.py 2009-03-25 11:41:03 +0000 | |||
827 | @@ -0,0 +1,182 @@ | |||
828 | 1 | # Copyright 2009 Canonical Ltd. All rights reserved. | ||
829 | 2 | |||
830 | 3 | """Database garbage collection.""" | ||
831 | 4 | |||
832 | 5 | __metaclass__ = type | ||
833 | 6 | __all__ = ['DailyDatabaseGarbageCollector', 'HourlyDatabaseGarbageCollector'] | ||
834 | 7 | |||
835 | 8 | import time | ||
836 | 9 | |||
837 | 10 | import transaction | ||
838 | 11 | from zope.component import getUtility | ||
839 | 12 | from zope.interface import implements | ||
840 | 13 | from storm.locals import SQL, Max, Min | ||
841 | 14 | |||
842 | 15 | from canonical.database.sqlbase import sqlvalues | ||
843 | 16 | from canonical.launchpad.database.codeimportresult import CodeImportResult | ||
844 | 17 | from canonical.launchpad.database.oauth import OAuthNonce | ||
845 | 18 | from canonical.launchpad.database.openidconsumer import OpenIDNonce | ||
846 | 19 | from canonical.launchpad.interfaces import IMasterStore | ||
847 | 20 | from canonical.launchpad.interfaces.looptuner import ITunableLoop | ||
848 | 21 | from canonical.launchpad.scripts.base import LaunchpadCronScript | ||
849 | 22 | from canonical.launchpad.utilities.looptuner import LoopTuner | ||
850 | 23 | from canonical.launchpad.webapp.interfaces import ( | ||
851 | 24 | IStoreSelector, MAIN_STORE, MASTER_FLAVOR) | ||
852 | 25 | |||
853 | 26 | |||
854 | 27 | ONE_DAY_IN_SECONDS = 24*60*60 | ||
855 | 28 | |||
856 | 29 | |||
857 | 30 | class TunableLoop: | ||
858 | 31 | implements(ITunableLoop) | ||
859 | 32 | |||
860 | 33 | goal_seconds = 4 | ||
861 | 34 | minimum_chunk_size = 1 | ||
862 | 35 | maximum_chunk_size = None # Override | ||
863 | 36 | cooldown_time = 0 | ||
864 | 37 | |||
865 | 38 | def run(self): | ||
866 | 39 | assert self.maximum_chunk_size is not None, "Did not override." | ||
867 | 40 | LoopTuner( | ||
868 | 41 | self, self.goal_seconds, | ||
869 | 42 | minimum_chunk_size = self.minimum_chunk_size, | ||
870 | 43 | maximum_chunk_size = self.maximum_chunk_size, | ||
871 | 44 | cooldown_time = self.cooldown_time).run() | ||
872 | 45 | |||
873 | 46 | |||
874 | 47 | class OAuthNoncePruner(TunableLoop): | ||
875 | 48 | """An ITunableLoop to prune old OAuthNonce records. | ||
876 | 49 | |||
877 | 50 | We remove all OAuthNonce records older than 1 day. | ||
878 | 51 | """ | ||
879 | 52 | maximum_chunk_size = 6*60*60 # 6 hours in seconds. | ||
880 | 53 | |||
881 | 54 | def __init__(self): | ||
882 | 55 | self.store = IMasterStore(OAuthNonce) | ||
883 | 56 | self.oldest_age = self.store.execute(""" | ||
884 | 57 | SELECT COALESCE(EXTRACT(EPOCH FROM | ||
885 | 58 | CURRENT_TIMESTAMP AT TIME ZONE 'UTC' | ||
886 | 59 | - MIN(request_timestamp)), 0) | ||
887 | 60 | FROM OAuthNonce | ||
888 | 61 | """).get_one()[0] | ||
889 | 62 | |||
890 | 63 | def isDone(self): | ||
891 | 64 | return self.oldest_age <= ONE_DAY_IN_SECONDS | ||
892 | 65 | |||
893 | 66 | def __call__(self, chunk_size): | ||
894 | 67 | self.oldest_age = max(ONE_DAY_IN_SECONDS, self.oldest_age - chunk_size) | ||
895 | 68 | |||
896 | 69 | self.store.find( | ||
897 | 70 | OAuthNonce, | ||
898 | 71 | OAuthNonce.request_timestamp < SQL( | ||
899 | 72 | "CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - interval '%d seconds'" | ||
900 | 73 | % self.oldest_age)).remove() | ||
901 | 74 | transaction.commit() | ||
902 | 75 | |||
903 | 76 | |||
904 | 77 | class OpenIDNoncePruner(TunableLoop): | ||
905 | 78 | """An ITunableLoop to prune old OpenIDNonce records. | ||
906 | 79 | |||
907 | 80 | We remove all OpenIDNonce records older than 1 day. | ||
908 | 81 | """ | ||
909 | 82 | maximum_chunk_size = 6*60*60 # 6 hours in seconds. | ||
910 | 83 | |||
911 | 84 | def __init__(self): | ||
912 | 85 | self.store = getUtility(IStoreSelector).get(MAIN_STORE, MASTER_FLAVOR) | ||
913 | 86 | self.earliest_timestamp = self.store.find( | ||
914 | 87 | Min(OpenIDNonce.timestamp)).one() | ||
915 | 88 | utc_now = int(time.mktime(time.gmtime())) | ||
916 | 89 | self.earliest_wanted_timestamp = utc_now - ONE_DAY_IN_SECONDS | ||
917 | 90 | |||
918 | 91 | def isDone(self): | ||
919 | 92 | return ( | ||
920 | 93 | self.earliest_timestamp is None | ||
921 | 94 | or self.earliest_timestamp >= self.earliest_wanted_timestamp) | ||
922 | 95 | |||
923 | 96 | def __call__(self, chunk_size): | ||
924 | 97 | self.earliest_timestamp = min( | ||
925 | 98 | self.earliest_wanted_timestamp, | ||
926 | 99 | self.earliest_timestamp + chunk_size) | ||
927 | 100 | |||
928 | 101 | self.store.find( | ||
929 | 102 | OpenIDNonce, | ||
930 | 103 | OpenIDNonce.timestamp < self.earliest_timestamp).remove() | ||
931 | 104 | transaction.commit() | ||
932 | 105 | |||
933 | 106 | |||
934 | 107 | class CodeImportResultPruner(TunableLoop): | ||
935 | 108 | """A TunableLoop to prune unwanted CodeImportResult rows. | ||
936 | 109 | |||
937 | 110 | Removes CodeImportResult rows if they are older than 30 days | ||
938 | 111 | and they are not one of the 4 most recent results for that | ||
939 | 112 | CodeImport. | ||
940 | 113 | """ | ||
941 | 114 | maximum_chunk_size = 100 | ||
942 | 115 | def __init__(self): | ||
943 | 116 | self.store = IMasterStore(CodeImportResult) | ||
944 | 117 | |||
945 | 118 | self.min_code_import = self.store.find( | ||
946 | 119 | Min(CodeImportResult.code_importID)).one() | ||
947 | 120 | self.max_code_import = self.store.find( | ||
948 | 121 | Max(CodeImportResult.code_importID)).one() | ||
949 | 122 | |||
950 | 123 | self.next_code_import_id = self.min_code_import | ||
951 | 124 | |||
952 | 125 | def isDone(self): | ||
953 | 126 | return ( | ||
954 | 127 | self.min_code_import is None | ||
955 | 128 | or self.next_code_import_id > self.max_code_import) | ||
956 | 129 | |||
957 | 130 | def __call__(self, chunk_size): | ||
958 | 131 | self.store.execute(""" | ||
959 | 132 | DELETE FROM CodeImportResult | ||
960 | 133 | WHERE | ||
961 | 134 | CodeImportResult.date_created | ||
962 | 135 | < CURRENT_TIMESTAMP AT TIME ZONE 'UTC' | ||
963 | 136 | - interval '30 days' | ||
964 | 137 | AND CodeImportResult.code_import >= %s | ||
965 | 138 | AND CodeImportResult.code_import < %s + %s | ||
966 | 139 | AND CodeImportResult.id NOT IN ( | ||
967 | 140 | SELECT LatestResult.id | ||
968 | 141 | FROM CodeImportResult AS LatestResult | ||
969 | 142 | WHERE | ||
970 | 143 | LatestResult.code_import | ||
971 | 144 | = CodeImportResult.code_import | ||
972 | 145 | ORDER BY LatestResult.date_created DESC | ||
973 | 146 | LIMIT 4) | ||
974 | 147 | """ % sqlvalues( | ||
975 | 148 | self.next_code_import_id, | ||
976 | 149 | self.next_code_import_id, | ||
977 | 150 | chunk_size)) | ||
978 | 151 | self.next_code_import_id += chunk_size | ||
979 | 152 | transaction.commit() | ||
980 | 153 | |||
981 | 154 | |||
982 | 155 | class BaseDatabaseGarbageCollector(LaunchpadCronScript): | ||
983 | 156 | """Abstract base class to run a collection of TunableLoops.""" | ||
984 | 157 | script_name = None # Script name for locking and database user. Override. | ||
985 | 158 | tunable_loops = None # Collection of TunableLoops. Override. | ||
986 | 159 | |||
987 | 160 | def __init__(self, test_args=None): | ||
988 | 161 | super(BaseDatabaseGarbageCollector, self).__init__( | ||
989 | 162 | self.script_name, dbuser=self.script_name, test_args=test_args) | ||
990 | 163 | |||
991 | 164 | def main(self): | ||
992 | 165 | for tunable_loop in self.tunable_loops: | ||
993 | 166 | self.logger.info("Running %s" % tunable_loop.__name__) | ||
994 | 167 | tunable_loop().run() | ||
995 | 168 | |||
996 | 169 | |||
997 | 170 | class HourlyDatabaseGarbageCollector(BaseDatabaseGarbageCollector): | ||
998 | 171 | script_name = 'garbo-hourly' | ||
999 | 172 | tunable_loops = [ | ||
1000 | 173 | OAuthNoncePruner, | ||
1001 | 174 | OpenIDNoncePruner, | ||
1002 | 175 | ] | ||
1003 | 176 | |||
1004 | 177 | class DailyDatabaseGarbageCollector(BaseDatabaseGarbageCollector): | ||
1005 | 178 | script_name = 'garbo-daily' | ||
1006 | 179 | tunable_loops = [ | ||
1007 | 180 | CodeImportResultPruner, | ||
1008 | 181 | ] | ||
1009 | 182 | |||
1010 | 0 | 183 | ||
1011 | === added file 'lib/canonical/launchpad/scripts/tests/test_garbo.py' | |||
1012 | --- lib/canonical/launchpad/scripts/tests/test_garbo.py 1970-01-01 00:00:00 +0000 | |||
1013 | +++ lib/canonical/launchpad/scripts/tests/test_garbo.py 2009-03-25 11:41:03 +0000 | |||
1014 | @@ -0,0 +1,192 @@ | |||
1015 | 1 | # Copyright 2009 Canonical Ltd. All rights reserved. | ||
1016 | 2 | |||
1017 | 3 | """Test the database garbage collector.""" | ||
1018 | 4 | |||
1019 | 5 | __metaclass__ = type | ||
1020 | 6 | __all__ = [] | ||
1021 | 7 | |||
1022 | 8 | from datetime import datetime, timedelta | ||
1023 | 9 | import time | ||
1024 | 10 | import unittest | ||
1025 | 11 | |||
1026 | 12 | from pytz import UTC | ||
1027 | 13 | from storm.locals import Min | ||
1028 | 14 | import transaction | ||
1029 | 15 | |||
1030 | 16 | from canonical.launchpad.database.codeimportresult import CodeImportResult | ||
1031 | 17 | from canonical.launchpad.database.oauth import OAuthNonce | ||
1032 | 18 | from canonical.launchpad.database.openidconsumer import OpenIDNonce | ||
1033 | 19 | from canonical.launchpad.interfaces import IMasterStore | ||
1034 | 20 | from canonical.launchpad.interfaces.codeimportresult import ( | ||
1035 | 21 | CodeImportResultStatus) | ||
1036 | 22 | from canonical.launchpad.testing import TestCase | ||
1037 | 23 | from canonical.launchpad.scripts.garbo import ( | ||
1038 | 24 | DailyDatabaseGarbageCollector, HourlyDatabaseGarbageCollector) | ||
1039 | 25 | from canonical.launchpad.scripts.tests import run_script | ||
1040 | 26 | from canonical.launchpad.scripts.logger import QuietFakeLogger | ||
1041 | 27 | from canonical.testing.layers import ( | ||
1042 | 28 | DatabaseLayer, LaunchpadScriptLayer, LaunchpadZopelessLayer) | ||
1043 | 29 | |||
1044 | 30 | |||
1045 | 31 | class TestGarboScript(TestCase): | ||
1046 | 32 | layer = LaunchpadScriptLayer | ||
1047 | 33 | |||
1048 | 34 | def test_daily_script(self): | ||
1049 | 35 | """Ensure garbo-daily.py actually runs.""" | ||
1050 | 36 | rv, out, err = run_script( | ||
1051 | 37 | "cronscripts/garbo-daily.py", ["-q"], expect_returncode=0) | ||
1052 | 38 | self.failIf(out.strip(), "Output to stdout: %s" % out) | ||
1053 | 39 | self.failIf(err.strip(), "Output to stderr: %s" % err) | ||
1054 | 40 | DatabaseLayer.force_dirty_database() | ||
1055 | 41 | |||
1056 | 42 | def test_hourly_script(self): | ||
1057 | 43 | """Ensure garbo-hourly.py actually runs.""" | ||
1058 | 44 | rv, out, err = run_script( | ||
1059 | 45 | "cronscripts/garbo-hourly.py", ["-q"], expect_returncode=0) | ||
1060 | 46 | self.failIf(out.strip(), "Output to stdout: %s" % out) | ||
1061 | 47 | self.failIf(err.strip(), "Output to stderr: %s" % err) | ||
1062 | 48 | |||
1063 | 49 | |||
1064 | 50 | class TestGarbo(TestCase): | ||
1065 | 51 | layer = LaunchpadZopelessLayer | ||
1066 | 52 | |||
1067 | 53 | def setUp(self): | ||
1068 | 54 | super(TestGarbo, self).setUp() | ||
1069 | 55 | # Run the garbage collectors to remove any existing garbage, | ||
1070 | 56 | # starting us in a known state. | ||
1071 | 57 | self.runDaily() | ||
1072 | 58 | self.runHourly() | ||
1073 | 59 | |||
1074 | 60 | def runDaily(self): | ||
1075 | 61 | LaunchpadZopelessLayer.switchDbUser('garbo-daily') | ||
1076 | 62 | collector = DailyDatabaseGarbageCollector(test_args=[]) | ||
1077 | 63 | collector.logger = QuietFakeLogger() | ||
1078 | 64 | collector.main() | ||
1079 | 65 | |||
1080 | 66 | def runHourly(self): | ||
1081 | 67 | LaunchpadZopelessLayer.switchDbUser('garbo-hourly') | ||
1082 | 68 | collector = HourlyDatabaseGarbageCollector(test_args=[]) | ||
1083 | 69 | collector.logger = QuietFakeLogger() | ||
1084 | 70 | collector.main() | ||
1085 | 71 | |||
1086 | 72 | def test_OAuthNoncePruner(self): | ||
1087 | 73 | store = IMasterStore(OAuthNonce) | ||
1088 | 74 | now = datetime.utcnow().replace(tzinfo=UTC) | ||
1089 | 75 | timestamps = [ | ||
1090 | 76 | now - timedelta(days=2), # Garbage | ||
1091 | 77 | now - timedelta(days=1) - timedelta(seconds=60), # Garbage | ||
1092 | 78 | now - timedelta(days=1) + timedelta(seconds=60), # Not garbage | ||
1093 | 79 | now, # Not garbage | ||
1094 | 80 | ] | ||
1095 | 81 | LaunchpadZopelessLayer.switchDbUser('testadmin') | ||
1096 | 82 | |||
1097 | 83 | # Make sure we start with 0 nonces. | ||
1098 | 84 | self.failUnlessEqual(store.find(OAuthNonce).count(), 0) | ||
1099 | 85 | |||
1100 | 86 | for timestamp in timestamps: | ||
1101 | 87 | OAuthNonce( | ||
1102 | 88 | access_tokenID=1, | ||
1103 | 89 | request_timestamp = timestamp, | ||
1104 | 90 | nonce = str(timestamp)) | ||
1105 | 91 | transaction.commit() | ||
1106 | 92 | |||
1107 | 93 | # Make sure we have 4 nonces now. | ||
1108 | 94 | self.failUnlessEqual(store.find(OAuthNonce).count(), 4) | ||
1109 | 95 | |||
1110 | 96 | self.runHourly() | ||
1111 | 97 | |||
1112 | 98 | # Now back to two, having removed the two garbage entries. | ||
1113 | 99 | self.failUnlessEqual(store.find(OAuthNonce).count(), 2) | ||
1114 | 100 | |||
1115 | 101 | # And none of them are older than a day. | ||
1116 | 102 | # Hmm... why is it I'm putting tz aware datetimes in and getting | ||
1117 | 103 | # naive datetimes back? Bug in the SQLObject compatibility layer? | ||
1118 | 104 | # Test is still fine as we know the timezone. | ||
1119 | 105 | self.failUnless( | ||
1120 | 106 | store.find( | ||
1121 | 107 | Min(OAuthNonce.request_timestamp)).one().replace(tzinfo=UTC) | ||
1122 | 108 | >= now - timedelta(days=1)) | ||
1123 | 109 | |||
1124 | 110 | def test_OpenIDNoncePruner(self): | ||
1125 | 111 | now = int(time.mktime(time.gmtime())) | ||
1126 | 112 | MINUTES = 60 | ||
1127 | 113 | HOURS = 60 * 60 | ||
1128 | 114 | DAYS = 24 * HOURS | ||
1129 | 115 | timestamps = [ | ||
1130 | 116 | now - 2 * DAYS, # Garbage | ||
1131 | 117 | now - 1 * DAYS - 1 * MINUTES, # Garbage | ||
1132 | 118 | now - 1 * DAYS + 1 * MINUTES, # Not garbage | ||
1133 | 119 | now, # Not garbage | ||
1134 | 120 | ] | ||
1135 | 121 | LaunchpadZopelessLayer.switchDbUser('testadmin') | ||
1136 | 122 | |||
1137 | 123 | store = IMasterStore(OpenIDNonce) | ||
1138 | 124 | |||
1139 | 125 | # Make sure we start with 0 nonces. | ||
1140 | 126 | self.failUnlessEqual(store.find(OpenIDNonce).count(), 0) | ||
1141 | 127 | |||
1142 | 128 | for timestamp in timestamps: | ||
1143 | 129 | nonce = store.add(OpenIDNonce()) | ||
1144 | 130 | nonce.server_url = unicode(timestamp) | ||
1145 | 131 | nonce.timestamp = timestamp | ||
1146 | 132 | nonce.salt = u'aa' | ||
1147 | 133 | store.add(nonce) | ||
1148 | 134 | transaction.commit() | ||
1149 | 135 | |||
1150 | 136 | # Make sure we have 4 nonces now. | ||
1151 | 137 | self.failUnlessEqual(store.find(OpenIDNonce).count(), 4) | ||
1152 | 138 | |||
1153 | 139 | # Run the garbage collector. | ||
1154 | 140 | self.runHourly() | ||
1155 | 141 | |||
1156 | 142 | # We should now have 2 nonces. | ||
1157 | 143 | self.failUnlessEqual(store.find(OpenIDNonce).count(), 2) | ||
1158 | 144 | |||
1159 | 145 | # And none of them are older than 1 day | ||
1160 | 146 | earliest = store.find(Min(OpenIDNonce.timestamp)).one() | ||
1161 | 147 | self.failUnless(earliest >= now - 24*60*60, 'Still have old nonces') | ||
1162 | 148 | |||
1163 | 149 | def test_CodeImportResultPruner(self): | ||
1164 | 150 | now = datetime.utcnow().replace(tzinfo=UTC) | ||
1165 | 151 | store = IMasterStore(CodeImportResult) | ||
1166 | 152 | |||
1167 | 153 | def new_code_import_result(timestamp): | ||
1168 | 154 | LaunchpadZopelessLayer.switchDbUser('testadmin') | ||
1169 | 155 | CodeImportResult( | ||
1170 | 156 | date_created=timestamp, | ||
1171 | 157 | code_importID=1, machineID=1, requesting_userID=1, | ||
1172 | 158 | status=CodeImportResultStatus.FAILURE, | ||
1173 | 159 | date_job_started=timestamp) | ||
1174 | 160 | transaction.commit() | ||
1175 | 161 | |||
1176 | 162 | new_code_import_result(now - timedelta(days=60)) | ||
1177 | 163 | new_code_import_result(now - timedelta(days=19)) | ||
1178 | 164 | new_code_import_result(now - timedelta(days=20)) | ||
1179 | 165 | new_code_import_result(now - timedelta(days=21)) | ||
1180 | 166 | |||
1181 | 167 | # Run the garbage collector | ||
1182 | 168 | self.runDaily() | ||
1183 | 169 | |||
1184 | 170 | # Nothing is removed, because we always keep the 4 latest. | ||
1185 | 171 | self.failUnlessEqual( | ||
1186 | 172 | store.find(CodeImportResult).count(), 4) | ||
1187 | 173 | |||
1188 | 174 | new_code_import_result(now - timedelta(days=31)) | ||
1189 | 175 | self.runDaily() | ||
1190 | 176 | self.failUnlessEqual( | ||
1191 | 177 | store.find(CodeImportResult).count(), 4) | ||
1192 | 178 | |||
1193 | 179 | new_code_import_result(now - timedelta(days=29)) | ||
1194 | 180 | self.runDaily() | ||
1195 | 181 | self.failUnlessEqual( | ||
1196 | 182 | store.find(CodeImportResult).count(), 4) | ||
1197 | 183 | |||
1198 | 184 | # We now have no CodeImportResults older than 30 days | ||
1199 | 185 | self.failUnless( | ||
1200 | 186 | store.find( | ||
1201 | 187 | Min(CodeImportResult.date_created)).one().replace(tzinfo=UTC) | ||
1202 | 188 | >= now - timedelta(days=30)) | ||
1203 | 189 | |||
1204 | 190 | |||
1205 | 191 | def test_suite(): | ||
1206 | 192 | return unittest.TestLoader().loadTestsFromName(__name__) |
The first cut of the database garbage collector. This is Oscar the Grounch, originally conceived when Launchpad was just an ER diagram.
I expect the framework will grow over time. This first version just prunes our Nonce tables and CodeImportResult entries.
There are some other cronscripts that could be folded in to this framework.
Some DB tweaks snuck in during the work.