Merge lp:~al-maisan/launchpad/newuris-399186 into lp:launchpad/db-devel

Proposed by Muharem Hrnjadovic
Status: Merged
Merged at revision: not available
Proposed branch: lp:~al-maisan/launchpad/newuris-399186
Merge into: lp:launchpad/db-devel
Diff against target: 545 lines
7 files modified
lib/lp/soyuz/browser/configure.zcml (+1/-1)
lib/lp/soyuz/browser/packageset.py (+19/-0)
lib/lp/soyuz/interfaces/archivepermission.py (+9/-0)
lib/lp/soyuz/interfaces/packageset.py (+5/-5)
lib/lp/soyuz/model/archivepermission.py (+6/-1)
lib/lp/soyuz/model/packageset.py (+9/-1)
lib/lp/soyuz/stories/webservice/xx-packageset.txt (+93/-52)
To merge this branch: bzr merge lp:~al-maisan/launchpad/newuris-399186
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Review via email: mp+14204@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Muharem Hrnjadovic (al-maisan) wrote :

Hello there!

a branch that introduces the association between package sets and distro
series has already landed on db-devel.

Package set names are now *not* globally unique any more but only unique
within the context of a distro series.

The branch at hand revises the package set traversal rules accordingly.

Pre-implementation call with Michael Nelson.

Tests to run:

    bin/test -vvt packageset

No pertinent "make lint" errors or warnings.

Revision history for this message
Abel Deuring (adeuring) :
review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/soyuz/browser/configure.zcml'
2--- lib/lp/soyuz/browser/configure.zcml 2009-10-22 10:33:00 +0000
3+++ lib/lp/soyuz/browser/configure.zcml 2009-10-30 10:10:25 +0000
4@@ -783,7 +783,7 @@
5 />
6 <browser:url
7 for="lp.soyuz.interfaces.packageset.IPackageset"
8- path_expression="name"
9+ path_expression="string:${distroseries/name}/${name}"
10 parent_utility="lp.soyuz.interfaces.packageset.IPackagesetSet"
11 />
12 <browser:url
13
14=== modified file 'lib/lp/soyuz/browser/packageset.py'
15--- lib/lp/soyuz/browser/packageset.py 2009-06-30 16:56:07 +0000
16+++ lib/lp/soyuz/browser/packageset.py 2009-10-30 10:10:25 +0000
17@@ -17,3 +17,22 @@
18 class PackagesetSetNavigation(GetitemNavigation):
19 """Navigation methods for PackagesetSet."""
20 usedfor = IPackagesetSet
21+
22+ def traverse(self, distroseries):
23+ """Traverse package sets in distro series context.
24+
25+ The URI fragment of interest is:
26+
27+ /package-sets/lucid/mozilla
28+
29+ where 'lucid' is the distro series and 'mozilla' is the package set
30+ *name* respectively.
31+ """
32+ if self.request.stepstogo:
33+ # The package set name follows after the distro series.
34+ ps_name = self.request.stepstogo.consume()
35+ return self.context.getByName(ps_name, distroseries=distroseries)
36+
37+ # Otherwise return None (to trigger a NotFound error).
38+ return None
39+
40
41=== modified file 'lib/lp/soyuz/interfaces/archivepermission.py'
42--- lib/lp/soyuz/interfaces/archivepermission.py 2009-08-03 17:10:12 +0000
43+++ lib/lp/soyuz/interfaces/archivepermission.py 2009-10-30 10:10:25 +0000
44@@ -284,6 +284,9 @@
45 def uploadersForPackageset(archive, packageset, direct_permissions=True):
46 """The `ArchivePermission` records for uploaders to the package set.
47
48+ Please note: if a package set *name* is passed the respective
49+ package set in the current distro series will be used.
50+
51 :param archive: The archive the permission applies to.
52 :param packageset: An `IPackageset` or a string package set name.
53 :param direct_permissions: If True only consider permissions granted
54@@ -332,6 +335,9 @@
55 def newPackagesetUploader(archive, person, packageset, explicit=False):
56 """Create and return a new `ArchivePermission` for an uploader.
57
58+ Please note: if a package set *name* is passed the respective
59+ package set in the current distro series will be used.
60+
61 :param archive: The archive the permission applies to.
62 :param person: An `IPerson` for whom you want to add permission.
63 :param packageset: An `IPackageset` or a string package set name.
64@@ -379,6 +385,9 @@
65 def deletePackagesetUploader(archive, person, packageset, explicit=False):
66 """Revoke upload permissions for a person.
67
68+ Please note: if a package set *name* is passed the respective
69+ package set in the current distro series will be used.
70+
71 :param archive: The archive the permission applies to.
72 :param person: An `IPerson` for whom you want to revoke permission.
73 :param packageset: An `IPackageset` or a string package set name.
74
75=== modified file 'lib/lp/soyuz/interfaces/packageset.py'
76--- lib/lp/soyuz/interfaces/packageset.py 2009-10-27 23:40:24 +0000
77+++ lib/lp/soyuz/interfaces/packageset.py 2009-10-30 10:10:25 +0000
78@@ -37,7 +37,7 @@
79 """Raised when we try to look up an PackageSet that doesn't exist."""
80 # Bad request.
81 webservice_error(400)
82- _message_prefix = "No such packageset"
83+ _message_prefix = "No such package set (in the specified distro series)"
84
85
86 class DuplicatePackagesetName(Exception):
87@@ -68,17 +68,17 @@
88 title=_("Description"), required=True, readonly=True,
89 description=_("The description for the package set at hand.")))
90
91- distroseries = Reference(
92+ distroseries = exported(Reference(
93 IDistroSeries, title=_("Distribution series"), required=True,
94 readonly=True,
95 description=_(
96- "The distroseries to which this package set is related."))
97+ "The distroseries to which this package set is related.")))
98
99 packagesetgroup = Reference(
100- IPackagesetGroup, title=_('Packageset group'), required=True,
101+ IPackagesetGroup, title=_('Package set group'), required=True,
102 readonly=True,
103 description=_(
104- 'Used internally to link packagesets across distroseries'))
105+ 'Used internally to link package sets across distro series.'))
106
107 def sourcesIncluded(direct_inclusion=False):
108 """Get all source names associated with this package set.
109
110=== modified file 'lib/lp/soyuz/model/archivepermission.py'
111--- lib/lp/soyuz/model/archivepermission.py 2009-07-28 21:52:56 +0000
112+++ lib/lp/soyuz/model/archivepermission.py 2009-10-30 10:10:25 +0000
113@@ -22,6 +22,7 @@
114 from canonical.database.enumcol import EnumCol
115 from canonical.database.sqlbase import sqlvalues, SQLBase
116
117+from lp.registry.interfaces.distribution import IDistributionSet
118 from lp.soyuz.interfaces.archive import ComponentNotFound
119 from lp.soyuz.interfaces.archivepermission import (
120 ArchivePermissionType, IArchivePermission, IArchivePermissionSet,
121@@ -312,9 +313,13 @@
122 def _nameToPackageset(self, packageset):
123 """Helper to convert a possible string name to IPackageset."""
124 if isinstance(packageset, basestring):
125+ # A package set name was passed, assume the current distro series.
126+ ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
127 name = packageset
128 store = IStore(Packageset)
129- packageset = store.find(Packageset, name=name).one()
130+ packageset = store.find(
131+ Packageset, name=name,
132+ distroseries=ubuntu.currentseries).one()
133 if packageset is not None:
134 return packageset
135 else:
136
137=== modified file 'lib/lp/soyuz/model/packageset.py'
138--- lib/lp/soyuz/model/packageset.py 2009-10-27 15:42:04 +0000
139+++ lib/lp/soyuz/model/packageset.py 2009-10-30 10:10:25 +0000
140@@ -14,6 +14,7 @@
141 from zope.interface import implements
142
143 from canonical.launchpad.interfaces.lpstorm import IMasterStore, IStore
144+from canonical.launchpad.webapp.interfaces import NotFoundError
145 from lp.registry.interfaces.distribution import IDistributionSet
146 from lp.registry.interfaces.sourcepackagename import (
147 ISourcePackageName, ISourcePackageNameSet)
148@@ -350,11 +351,17 @@
149 if not isinstance(name, unicode):
150 name = unicode(name, 'utf-8')
151
152+ ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
153 extra_args = []
154 if distroseries is not None:
155+ # If the user just passed a distro series name, look it up.
156+ if isinstance(distroseries, basestring):
157+ try:
158+ distroseries = ubuntu[distroseries]
159+ except NotFoundError:
160+ raise NoSuchPackageSet(distroseries)
161 extra_args.append(Packageset.distroseries == distroseries)
162 else:
163- ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
164 extra_args.append(Packageset.distroseries == ubuntu.currentseries)
165
166 package_set = store.find(
167@@ -362,6 +369,7 @@
168
169 if package_set is None:
170 raise NoSuchPackageSet(name)
171+
172 return package_set
173
174 def getByOwner(self, owner):
175
176=== modified file 'lib/lp/soyuz/stories/webservice/xx-packageset.txt'
177--- lib/lp/soyuz/stories/webservice/xx-packageset.txt 2009-08-20 04:46:48 +0000
178+++ lib/lp/soyuz/stories/webservice/xx-packageset.txt 2009-10-30 10:10:25 +0000
179@@ -52,16 +52,16 @@
180 Can we access it via the webservice API as well?
181
182 >>> logout()
183- >>> umbrella = webservice.get("/package-sets/umbrella").jsonBody()
184+ >>> umbrella = webservice.get("/package-sets/hoary/umbrella").jsonBody()
185 >>> print umbrella['self_link']
186- http://api.launchpad.dev/beta/package-sets/umbrella
187+ http://api.launchpad.dev/beta/package-sets/hoary/umbrella
188
189 `PackageSet`s can be looked up by name.
190
191 >>> response = webservice.named_get(
192 ... '/package-sets', 'getByName', {}, name=u'umbrella')
193 >>> print response.jsonBody()['self_link']
194- http://api.launchpad.dev/beta/package-sets/umbrella
195+ http://api.launchpad.dev/beta/package-sets/hoary/umbrella
196
197 When a `PackageSet` cannot be found, an error is returned.
198
199@@ -70,9 +70,17 @@
200 >>> print response
201 HTTP/1.1 400 Bad Request
202 ...
203- NoSuchPackageSet: No such packageset: 'not-found'.
204+ No such package set (in the specified distro series): 'not-found'.
205+ ...
206 <BLANKLINE>
207
208+Here's an example with a funny URL concoted by a "smart" user.
209+
210+ >>> response = webservice.get("/package-sets/lucid-plus-1/umbrella/+pwn")
211+ >>> print response
212+ HTTP/1.1 404 Not Found
213+ ...
214+
215 Populate the 'umbrella' package set with source packages.
216
217 >>> from canonical.launchpad.webapp.interfaces import (
218@@ -81,7 +89,7 @@
219 >>> store = getUtility(IStoreSelector).get(MAIN_STORE, DEFAULT_FLAVOR)
220 >>> all_spns = store.find(SourcePackageName)
221 >>> response = webservice.named_post(
222- ... '/package-sets/umbrella', 'addSources', {},
223+ ... '/package-sets/hoary/umbrella', 'addSources', {},
224 ... names=[spn.name for spn in all_spns])
225 >>> print response
226 HTTP/1.1 200 Ok
227@@ -91,7 +99,7 @@
228 exist will not fail. Non-existing source package names are *ignored*.
229
230 >>> response = webservice.named_post(
231- ... '/package-sets/umbrella', 'addSources', {},
232+ ... '/package-sets/hoary/umbrella', 'addSources', {},
233 ... names=[u'does-not-exist'])
234 >>> print response
235 HTTP/1.1 200 Ok
236@@ -99,7 +107,7 @@
237 null
238
239 >>> response = webservice.named_post(
240- ... '/package-sets/umbrella', 'removeSources', {},
241+ ... '/package-sets/hoary/umbrella', 'removeSources', {},
242 ... names=[u'does-not-exist'])
243 >>> print response
244 HTTP/1.1 200 Ok
245@@ -109,7 +117,7 @@
246 Let's see what we got.
247
248 >>> response = webservice.named_get(
249- ... '/package-sets/umbrella', 'getSourcesIncluded', {})
250+ ... '/package-sets/hoary/umbrella', 'getSourcesIncluded', {})
251 >>> print response
252 HTTP/1.1 200 Ok
253 ...
254@@ -136,7 +144,7 @@
255 from the 'umbrella' package set.
256
257 >>> response = webservice.named_post(
258- ... '/package-sets/umbrella', 'removeSources', {},
259+ ... '/package-sets/hoary/umbrella', 'removeSources', {},
260 ... names=["foobar", "iceweasel"])
261 >>> print response
262 HTTP/1.1 200 Ok
263@@ -146,7 +154,7 @@
264 from the list below.
265
266 >>> response = webservice.named_get(
267- ... '/package-sets/umbrella', 'getSourcesIncluded', {})
268+ ... '/package-sets/hoary/umbrella', 'getSourcesIncluded', {})
269 >>> print response
270 HTTP/1.1 200 Ok
271 ...
272@@ -176,13 +184,13 @@
273
274 >>> response = webservice.get("/package-sets/")
275 >>> print_payload(response)
276- http://api.launchpad.dev/beta/package-sets/umbrella
277+ http://api.launchpad.dev/beta/package-sets/hoary/umbrella
278
279 Package sets may include other package sets (as subsets). At this point,
280 however, we only have the 'umbrella' package set. It hence has no subsets.
281
282 >>> response = webservice.named_get(
283- ... '/package-sets/umbrella', 'setsIncluded', {})
284+ ... '/package-sets/hoary/umbrella', 'setsIncluded', {})
285 >>> print response
286 HTTP/1.1 200 Ok
287 ...
288@@ -245,27 +253,27 @@
289 * languagepack
290
291 >>> response = webservice.named_post(
292- ... '/package-sets/umbrella', 'addSubsets', {},
293+ ... '/package-sets/hoary/umbrella', 'addSubsets', {},
294 ... names=[u'gnome', u'mozilla'])
295 >>> print response
296 HTTP/1.1 200 Ok
297 ...
298
299 >>> response = webservice.named_post(
300- ... '/package-sets/gnome', 'addSubsets', {}, names=[u'languagepack'])
301+ ... '/package-sets/hoary/gnome', 'addSubsets', {}, names=[u'languagepack'])
302 >>> print response
303 HTTP/1.1 200 Ok
304 ...
305
306 >>> response = webservice.named_post(
307- ... '/package-sets/thunderbird', 'addSubsets', {},
308+ ... '/package-sets/hoary/thunderbird', 'addSubsets', {},
309 ... names=[u'languagepack'])
310 >>> print response
311 HTTP/1.1 200 Ok
312 ...
313
314 >>> response = webservice.named_post(
315- ... '/package-sets/mozilla', 'addSubsets', {},
316+ ... '/package-sets/hoary/mozilla', 'addSubsets', {},
317 ... names=[u'firefox', u'thunderbird'])
318 >>> print response
319 HTTP/1.1 200 Ok
320@@ -275,7 +283,7 @@
321 non-existing package sets will not fail.
322
323 >>> response = webservice.named_post(
324- ... '/package-sets/thunderbird', 'addSubsets', {},
325+ ... '/package-sets/hoary/thunderbird', 'addSubsets', {},
326 ... names=[u'does-not-exist'])
327 >>> print response
328 HTTP/1.1 200 Ok
329@@ -283,7 +291,7 @@
330 null
331
332 >>> response = webservice.named_post(
333- ... '/package-sets/thunderbird', 'removeSubsets', {},
334+ ... '/package-sets/hoary/thunderbird', 'removeSubsets', {},
335 ... names=[u'does-not-exist'])
336 >>> print response
337 HTTP/1.1 200 Ok
338@@ -293,49 +301,49 @@
339 The 'umbrella' package set should have plenty of subsets now.
340
341 >>> response = webservice.named_get(
342- ... '/package-sets/umbrella', 'setsIncluded', {})
343+ ... '/package-sets/hoary/umbrella', 'setsIncluded', {})
344 >>> print_payload(response)
345- http://api.launchpad.dev/beta/package-sets/firefox
346- http://api.launchpad.dev/beta/package-sets/gnome
347- http://api.launchpad.dev/beta/package-sets/languagepack
348- http://api.launchpad.dev/beta/package-sets/mozilla
349- http://api.launchpad.dev/beta/package-sets/thunderbird
350+ http://api.launchpad.dev/beta/package-sets/hoary/firefox
351+ http://api.launchpad.dev/beta/package-sets/hoary/gnome
352+ http://api.launchpad.dev/beta/package-sets/hoary/languagepack
353+ http://api.launchpad.dev/beta/package-sets/hoary/mozilla
354+ http://api.launchpad.dev/beta/package-sets/hoary/thunderbird
355
356 However only two of the above are direct subsets.
357
358 >>> response = webservice.named_get(
359- ... '/package-sets/umbrella', 'setsIncluded', {},
360+ ... '/package-sets/hoary/umbrella', 'setsIncluded', {},
361 ... direct_inclusion=True)
362 >>> print_payload(response)
363- http://api.launchpad.dev/beta/package-sets/gnome
364- http://api.launchpad.dev/beta/package-sets/mozilla
365+ http://api.launchpad.dev/beta/package-sets/hoary/gnome
366+ http://api.launchpad.dev/beta/package-sets/hoary/mozilla
367
368 Let's ask the question the other way around what package sets are including
369 a particular subset?
370
371 >>> response = webservice.named_get(
372- ... '/package-sets/languagepack', 'setsIncludedBy', {})
373+ ... '/package-sets/hoary/languagepack', 'setsIncludedBy', {})
374 >>> print_payload(response)
375- http://api.launchpad.dev/beta/package-sets/gnome
376- http://api.launchpad.dev/beta/package-sets/mozilla
377- http://api.launchpad.dev/beta/package-sets/thunderbird
378- http://api.launchpad.dev/beta/package-sets/umbrella
379+ http://api.launchpad.dev/beta/package-sets/hoary/gnome
380+ http://api.launchpad.dev/beta/package-sets/hoary/mozilla
381+ http://api.launchpad.dev/beta/package-sets/hoary/thunderbird
382+ http://api.launchpad.dev/beta/package-sets/hoary/umbrella
383
384 The list of package sets that *directly* include 'languagepack' will be
385 shorter because the transitive closure is ignored.
386
387 >>> response = webservice.named_get(
388- ... '/package-sets/languagepack', 'setsIncludedBy', {},
389+ ... '/package-sets/hoary/languagepack', 'setsIncludedBy', {},
390 ... direct_inclusion=True)
391 >>> print_payload(response)
392- http://api.launchpad.dev/beta/package-sets/gnome
393- http://api.launchpad.dev/beta/package-sets/thunderbird
394+ http://api.launchpad.dev/beta/package-sets/hoary/gnome
395+ http://api.launchpad.dev/beta/package-sets/hoary/thunderbird
396
397 We can remove subsets as well. In the example below 'thunderbird' will
398 stop including 'languagepack'.
399
400 >>> response = webservice.named_post(
401- ... '/package-sets/thunderbird', 'removeSubsets', {},
402+ ... '/package-sets/hoary/thunderbird', 'removeSubsets', {},
403 ... names=[u'languagepack'])
404 >>> print response
405 HTTP/1.1 200 Ok
406@@ -344,37 +352,37 @@
407 And, here we go, now 'languagepack' has only one direct predecessor: 'gnome'.
408
409 >>> response = webservice.named_get(
410- ... '/package-sets/languagepack', 'setsIncludedBy', {},
411+ ... '/package-sets/hoary/languagepack', 'setsIncludedBy', {},
412 ... direct_inclusion=True)
413 >>> print_payload(response)
414- http://api.launchpad.dev/beta/package-sets/gnome
415+ http://api.launchpad.dev/beta/package-sets/hoary/gnome
416
417 Let's add a few source packages to the 'firefox' and the 'thunderbird'
418 package sets.
419
420 >>> response = webservice.named_post(
421- ... '/package-sets/firefox', 'addSources', {},
422+ ... '/package-sets/hoary/firefox', 'addSources', {},
423 ... names=['at', 'mozilla-firefox', 'language-pack-de'])
424 >>> print response
425 HTTP/1.1 200 Ok
426 ...
427
428 >>> response = webservice.named_get(
429- ... '/package-sets/firefox', 'getSourcesIncluded', {})
430+ ... '/package-sets/hoary/firefox', 'getSourcesIncluded', {})
431 >>> print response
432 HTTP/1.1 200 Ok
433 ...
434 ["at", "language-pack-de", "mozilla-firefox"]
435
436 >>> response = webservice.named_post(
437- ... '/package-sets/thunderbird', 'addSources', {},
438+ ... '/package-sets/hoary/thunderbird', 'addSources', {},
439 ... names=['at', 'cnews', 'thunderbird', 'language-pack-de'])
440 >>> print response
441 HTTP/1.1 200 Ok
442 ...
443
444 >>> response = webservice.named_get(
445- ... '/package-sets/thunderbird', 'getSourcesIncluded', {})
446+ ... '/package-sets/hoary/thunderbird', 'getSourcesIncluded', {})
447 >>> print response
448 HTTP/1.1 200 Ok
449 ...
450@@ -386,9 +394,9 @@
451 ... '/package-sets/', 'setsIncludingSource', {},
452 ... sourcepackagename=u'mozilla-firefox')
453 >>> print_payload(response)
454- http://api.launchpad.dev/beta/package-sets/firefox
455- http://api.launchpad.dev/beta/package-sets/mozilla
456- http://api.launchpad.dev/beta/package-sets/umbrella
457+ http://api.launchpad.dev/beta/package-sets/hoary/firefox
458+ http://api.launchpad.dev/beta/package-sets/hoary/mozilla
459+ http://api.launchpad.dev/beta/package-sets/hoary/umbrella
460
461 Which package sets include the 'mozilla-firefox' source package *directly*?
462
463@@ -397,8 +405,8 @@
464 ... sourcepackagename=u'mozilla-firefox',
465 ... direct_inclusion=True)
466 >>> print_payload(response)
467- http://api.launchpad.dev/beta/package-sets/firefox
468- http://api.launchpad.dev/beta/package-sets/umbrella
469+ http://api.launchpad.dev/beta/package-sets/hoary/firefox
470+ http://api.launchpad.dev/beta/package-sets/hoary/umbrella
471
472 If a non-existing source package name is passed it returns an error.
473
474@@ -414,9 +422,9 @@
475 What source packages are shared by the 'firefox' and the 'thunderbird'
476 package sets?
477
478- >>> thunderbird = webservice.get("/package-sets/thunderbird").jsonBody()
479+ >>> thunderbird = webservice.get("/package-sets/hoary/thunderbird").jsonBody()
480 >>> response = webservice.named_get(
481- ... '/package-sets/firefox', 'getSourcesSharedBy', {},
482+ ... '/package-sets/hoary/firefox', 'getSourcesSharedBy', {},
483 ... other_package_set=thunderbird['self_link'])
484 >>> print response
485 HTTP/1.1 200 Ok
486@@ -426,16 +434,16 @@
487 How about the complement set i.e. the packages not shared?
488
489 >>> response = webservice.named_get(
490- ... '/package-sets/firefox', 'getSourcesNotSharedBy', {},
491+ ... '/package-sets/hoary/firefox', 'getSourcesNotSharedBy', {},
492 ... other_package_set=thunderbird['self_link'])
493 >>> print response
494 HTTP/1.1 200 Ok
495 ...
496 ["mozilla-firefox"]
497
498- >>> firefox = webservice.get("/package-sets/firefox").jsonBody()
499+ >>> firefox = webservice.get("/package-sets/hoary/firefox").jsonBody()
500 >>> response = webservice.named_get(
501- ... '/package-sets/thunderbird', 'getSourcesNotSharedBy', {},
502+ ... '/package-sets/hoary/thunderbird', 'getSourcesNotSharedBy', {},
503 ... other_package_set=firefox['self_link'])
504 >>> print response
505 HTTP/1.1 200 Ok
506@@ -443,6 +451,39 @@
507 ["cnews", "thunderbird"]
508
509
510+=== Package sets and distro series ===
511+
512+Every package set is associated with a distro series.
513+
514+ >>> from lazr.restful.testing.webservice import pprint_entry
515+ >>> mozilla = webservice.named_get(
516+ ... '/package-sets', 'getByName', {}, name=u'mozilla').jsonBody()
517+ >>> print mozilla['distroseries_link']
518+ http://api.launchpad.dev/beta/ubuntu/hoary
519+
520+
521+=== Related package sets ===
522+
523+When adding a package set we can specify that is to be related to another set
524+that exists already.
525+
526+ >>> grumpy = webservice.get("/ubuntu/grumpy").jsonBody()
527+ >>> print grumpy['self_link']
528+ http://api.launchpad.dev/beta/ubuntu/grumpy
529+
530+We are adding a new 'mozilla' package set to the 'grumpy' distro series and
531+it is related to 'mozilla' in 'hoary'.
532+
533+ >>> response = webservice.named_post(
534+ ... '/package-sets', 'new', {},
535+ ... name=u'mozilla',
536+ ... description=u'Contains all mozilla packages',
537+ ... owner=name12['self_link'], distroseries=grumpy['self_link'],
538+ ... related_set=mozilla['self_link'])
539+ >>> print response
540+ HTTP/1.1 201 Created
541+ ...
542+
543 == Archive permissions and package sets ==
544
545 Operating on package set based archive permissions is possible via

Subscribers

People subscribed via source and target branches

to status/vote changes: