Merge lp:~julian-edwards/launchpad/delete-packages-api-bug-687298 into lp:launchpad

Proposed by Julian Edwards on 2010-12-08
Status: Merged
Approved by: Julian Edwards on 2010-12-08
Approved revision: no longer in the source branch.
Merged at revision: 12033
Proposed branch: lp:~julian-edwards/launchpad/delete-packages-api-bug-687298
Merge into: lp:launchpad
Diff against target: 176 lines (+56/-16)
3 files modified
lib/lp/soyuz/interfaces/publishing.py (+15/-2)
lib/lp/soyuz/model/publishing.py (+13/-0)
lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt (+28/-14)
To merge this branch: bzr merge lp:~julian-edwards/launchpad/delete-packages-api-bug-687298
Reviewer Review Type Date Requested Status
Jelmer Vernooij (community) code 2010-12-08 Approve on 2010-12-08
Review via email: mp+43098@code.launchpad.net

Commit Message

When deleting source packages on the API, make sure their binaries are deleted too so they're not left in limbo.

Description of the Change

Currently when source packages are deleted on the API it leaves their binaries undeleted and in limbo. This causes the publisher to consider the packages for condemning each and every cycle it runs, which can cause huge delays (the data fixed in production caused by this bug has changed the cycle from 40 minutes to 5).

This branch fixes that by making a special requestDeletion() just for the API which calls requestDeletion() on IPublishingSet instead (which is what the UI does).

The story test is a little nasty I'm afraid, I had to also convert it to use a different distroseries that's set up for binary publications.

At some point it would be nice to convert it to a propert unit test, but not today.

To post a comment you must log in.
Jelmer Vernooij (jelmer) :
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/interfaces/publishing.py'
2--- lib/lp/soyuz/interfaces/publishing.py 2010-11-10 04:25:52 +0000
3+++ lib/lp/soyuz/interfaces/publishing.py 2010-12-08 16:12:15 +0000
4@@ -30,6 +30,7 @@
5 from lazr.restful.declarations import (
6 call_with,
7 export_as_webservice_entry,
8+ export_operation_as,
9 export_read_operation,
10 export_write_operation,
11 exported,
12@@ -235,16 +236,28 @@
13 class IPublishingEdit(Interface):
14 """Base interface for writeable Publishing classes."""
15
16+ def requestDeletion(removed_by, removal_comment=None):
17+ """Delete this publication.
18+
19+ :param removed_by: `IPerson` responsible for the removal.
20+ :param removal_comment: optional text describing the removal reason.
21+ """
22+
23 @call_with(removed_by=REQUEST_USER)
24 @operation_parameters(
25 removal_comment=TextLine(title=_("Removal comment"), required=False))
26+ @export_operation_as("requestDeletion")
27 @export_write_operation()
28- def requestDeletion(removed_by, removal_comment=None):
29- """Delete this publication.
30+ def api_requestDeletion(removed_by, removal_comment=None):
31+ """Delete this source and its binaries.
32
33 :param removed_by: `IPerson` responsible for the removal.
34 :param removal_comment: optional text describing the removal reason.
35 """
36+ # This is a special API method that allows a different code path
37+ # to the regular requestDeletion(). In the case of sources
38+ # getting deleted, it ensures source and binaries are both
39+ # deleted in tandem.
40
41
42 class IFilePublishing(Interface):
43
44=== modified file 'lib/lp/soyuz/model/publishing.py'
45--- lib/lp/soyuz/model/publishing.py 2010-12-01 11:26:57 +0000
46+++ lib/lp/soyuz/model/publishing.py 2010-12-08 16:12:15 +0000
47@@ -843,6 +843,13 @@
48 diff.diff_content, self.archive).http_url
49 return None
50
51+ def api_requestDeletion(self, removed_by, removal_comment=None):
52+ """See `IPublishingEdit`."""
53+ # Special deletion method for the api that makes sure binaries
54+ # get deleted too.
55+ getUtility(IPublishingSet).requestDeletion(
56+ [self], removed_by, removal_comment)
57+
58
59 class BinaryPackagePublishingHistory(SQLBase, ArchivePublisherBase):
60 """A binary package publishing record."""
61@@ -1216,6 +1223,12 @@
62
63 return dict(date_to_string(result) for result in results)
64
65+ def api_requestDeletion(self, removed_by, removal_comment=None):
66+ """See `IPublishingEdit`."""
67+ # Special deletion method for the api. We don't do anything
68+ # different here (yet).
69+ self.requestDeletion(removed_by, removal_comment)
70+
71
72 class PublishingSet:
73 """Utilities for manipulating publications in batches."""
74
75=== modified file 'lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt'
76--- lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2010-10-18 22:24:59 +0000
77+++ lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt 2010-12-08 16:12:15 +0000
78@@ -73,6 +73,7 @@
79
80 >>> distros = webservice.get("/distros").jsonBody()
81 >>> ubuntu = distros['entries'][0]
82+ >>> ubuntutest = distros['entries'][2]
83 >>> warty = webservice.named_get(
84 ... ubuntu['self_link'], 'getSeries',
85 ... name_or_version='warty').jsonBody()
86@@ -95,17 +96,21 @@
87 >>> from zope.component import getUtility
88 >>> from lp.registry.interfaces.distribution import IDistributionSet
89 >>> from lp.registry.interfaces.person import IPersonSet
90- >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
91- >>> warty_series = ubuntu.getSeries('warty')
92+ >>> from lp.soyuz.enums import PackagePublishingStatus
93 >>> cprov_ppa = getUtility(IPersonSet).getByName("cprov").archive
94- >>> discard = stp.getPubSource(
95- ... archive=cprov_ppa, sourcename="testwebservice",
96- ... distroseries=warty_series)
97+ >>> source = stp.getPubSource(
98+ ... archive=cprov_ppa, sourcename="testwebservice")
99+ >>> binaries = stp.getPubBinaries(
100+ ... binaryname="testwebservice-bin", pub_source=source,
101+ ... status=PackagePublishingStatus.PUBLISHED)
102 >>> logout()
103
104+ >>> breezy = webservice.named_get(
105+ ... ubuntutest['self_link'], 'getSeries',
106+ ... name_or_version='breezy-autotest').jsonBody()
107 >>> pubs = webservice.named_get(
108 ... cprov_archive['self_link'], 'getPublishedSources',
109- ... distro_series=warty['self_link'],
110+ ... distro_series=breezy['self_link'],
111 ... source_name="testwebservice").jsonBody()
112
113 >>> from lazr.restful.testing.webservice import pprint_entry
114@@ -117,8 +122,8 @@
115 date_published: None
116 date_removed: None
117 date_superseded: None
118- display_name: u'testwebservice 666 in warty'
119- distro_series_link: u'http://.../ubuntu/warty'
120+ display_name: u'testwebservice 666 in breezy-autotest'
121+ distro_series_link: u'http://.../ubuntutest/breezy-autotest'
122 package_creator_link: u'http://.../beta/~name16'
123 package_maintainer_link: u'http://.../beta/~name16'
124 package_signer_link: u'http://.../beta/~name16'
125@@ -158,7 +163,7 @@
126
127 >>> pubs = webservice.named_get(
128 ... cprov_archive['self_link'], 'getPublishedSources',
129- ... distro_series=warty['self_link'],
130+ ... distro_series=breezy['self_link'],
131 ... source_name="testwebservice").jsonBody()
132
133 >>> print pubs['entries'][0]['package_signer_link']
134@@ -213,20 +218,29 @@
135 >>> print pubs['entries'][0]['removal_comment']
136 No longer needed
137
138+The package's binaries are also marked for deletion:
139+
140+ >>> login("admin@canonical.com")
141+ >>> for bin in cprov_ppa.getAllPublishedBinaries(
142+ ... name="testwebservice-bin"):
143+ ... if bin.status != PackagePublishingStatus.DELETED:
144+ ... print "%s is not deleted when it should be" % bin.displayname
145+ ... else:
146+ ... print "%s deleted OK." % bin.displayname
147+ testwebservice-bin 666 in breezy-autotest i386 deleted OK.
148+ testwebservice-bin 666 in breezy-autotest hppa deleted OK.
149+
150+
151 Privacy
152 =======
153
154 Create a private PPA for Celso with some binaries.
155
156- >>> login("foo.bar@canonical.com")
157-
158 >>> from zope.component import getUtility
159 >>> from lp.registry.interfaces.distribution import IDistributionSet
160 >>> from lp.registry.interfaces.person import IPersonSet
161 >>> from lp.soyuz.tests.test_publishing import (
162 ... SoyuzTestPublisher)
163- >>> from lp.soyuz.enums import (
164- ... PackagePublishingStatus)
165 >>> cprov_db = getUtility(IPersonSet).getByName('cprov')
166 >>> ubuntu_db = getUtility(IDistributionSet).getByName('ubuntu')
167 >>> cprov_private_ppa_db = factory.makeArchive(
168@@ -385,7 +399,7 @@
169 []
170 [u'http://launchpad.dev/~cprov/+archive/ppa/+files/mozilla-firefox_0.9_i386.deb']
171 []
172- []
173+ [u'http://launchpad.dev/~cprov/+archive/ppa/+files/testwebservice-bin_666_all.deb']
174
175 The debdiff to a particular version can also be retrieved using the
176 packageDiffUrl() method. It takes one parameter, 'to_version' which