Merge lp:~cjwatson/launchpad/copies-respect-new into lp:launchpad

Proposed by Colin Watson
Status: Work in progress
Proposed branch: lp:~cjwatson/launchpad/copies-respect-new
Merge into: lp:launchpad
Diff against target: 146 lines (+67/-8)
3 files modified
lib/lp/soyuz/configure.zcml (+1/-2)
lib/lp/soyuz/model/packagecopyjob.py (+27/-6)
lib/lp/soyuz/tests/test_packagecopyjob.py (+39/-0)
To merge this branch: bzr merge lp:~cjwatson/launchpad/copies-respect-new
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+221529@code.launchpad.net

Commit message

Send copies to NEW if they contain binaries without overrides.

Description of the change

Make binaryful copies respect NEW. This is not ideal because it results in entries in the NEW queue which don't really explain why they're there; however, it's a first step towards a more reasonable representation of copies. This is particularly important to make sure that there's an opportunity for packages staged in PPAs to receive proper review when copied into the Ubuntu archive.

To post a comment you must log in.
Revision history for this message
Adam Conrad (adconrad) wrote :

So, until the queue redesign copies remain opaque, which means that can't be overridden until they're actually accepted. Will this change at least make sure ancestry does the expected thing (the code certainly seems to mention ancestry) and makes new binaries match the overrides of the source? For most cases, this should end up being the desired behaviour.

Revision history for this message
William Grant (wgrant) wrote :

This is going to block any binary copies to series (or distros!) with fewer arches, but otherwise seems fine.

review: Approve (code)
Revision history for this message
Colin Watson (cjwatson) wrote :

> So, until the queue redesign copies remain opaque, which means that can't be
> overridden until they're actually accepted.

Right. I know that this is only part of what we need; the patch includes a bug reference for the other major part of the problem. That's bigger, though, and I think that making sure things land in NEW at all is more immediately pressing. It's at least somewhat useful: for example, you can at least reject an upload if it's inappropriate.

William and I think that making binary overrides work on copies may not actually require the full redesign, although that would still be valuable for other reasons (e.g. making diffs work properly would be unutterably tedious with what we have now). We'd stuff the override data into the PU's JSON metadata much as we do now with source uploads, probably in the same format that we currently return from PU.getBinaryProperties, and hook up PU.getBinaryProperties and PU.overrideBinary to that; and we'd have to fish out those overrides in the PCJ, pass them down to the copier, and make the copier handle binary overrides, which is probably the largest chunk of work.

But I didn't want to do that in the same branch as this change, because it'll be a bit longer and I've given William more than enough gigantic branches to review lately ...

> Will this change at least make
> sure ancestry does the expected thing (the code certainly seems to mention
> ancestry) and makes new binaries match the overrides of the source? For most
> cases, this should end up being the desired behaviour.

All this change does is sometimes suspend the copy job and create a queue entry for it in a few more places. If the queue entry is accepted, then the copy job will be reprocessed from the start, applying overrides exactly as before.

When we implement the scheme above, we'll apply the archive's override policy when calculating the overrides that we stuff into the PU, which will result in reasonable defaults.

Revision history for this message
Colin Watson (cjwatson) wrote :

> So, until the queue redesign copies remain opaque, which means that can't be
> overridden until they're actually accepted.

Right. I know that this is only part of what we need; the patch includes a bug reference for the other major part of the problem. That's bigger, though, and I think that making sure things land in NEW at all is more immediately pressing. It's at least somewhat useful: for example, you can at least reject an upload if it's inappropriate.

William and I think that making binary overrides work on copies may not actually require the full redesign, although that would still be valuable for other reasons (e.g. making diffs work properly would be unutterably tedious with what we have now). We'd stuff the override data into the PU's JSON metadata much as we do now with source uploads, probably in the same format that we currently return from PU.getBinaryProperties, and hook up PU.getBinaryProperties and PU.overrideBinary to that; and we'd have to fish out those overrides in the PCJ, pass them down to the copier, and make the copier handle binary overrides, which is probably the largest chunk of work.

But I didn't want to do that in the same branch as this change, because it'll be a bit longer and I've given William more than enough gigantic branches to review lately ...

> Will this change at least make
> sure ancestry does the expected thing (the code certainly seems to mention
> ancestry) and makes new binaries match the overrides of the source? For most
> cases, this should end up being the desired behaviour.

All this change does is sometimes suspend the copy job and create a queue entry for it in a few more places. If the queue entry is accepted, then the copy job will be reprocessed from the start, applying overrides exactly as before.

When we implement the scheme above, we'll apply the archive's override policy when calculating the overrides that we stuff into the PU, which will result in reasonable defaults.

Revision history for this message
Colin Watson (cjwatson) wrote :

(Sorry for the duplicate. I blame the hotel's captive portal for confusing me.)

Unmerged revisions

17033. By Colin Watson

Send copies to NEW if they contain binaries without overrides.

17032. By Colin Watson

Remove reference to non-existent setNew attribute.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/soyuz/configure.zcml'
--- lib/lp/soyuz/configure.zcml 2014-02-18 11:40:52 +0000
+++ lib/lp/soyuz/configure.zcml 2014-05-30 12:14:46 +0000
@@ -1,4 +1,4 @@
1<!-- Copyright 2009-2013 Canonical Ltd. This software is licensed under the1<!-- Copyright 2009-2014 Canonical Ltd. This software is licensed under the
2 GNU Affero General Public License version 3 (see the file LICENSE).2 GNU Affero General Public License version 3 (see the file LICENSE).
3-->3-->
44
@@ -199,7 +199,6 @@
199 <require199 <require
200 permission="launchpad.Edit"200 permission="launchpad.Edit"
201 attributes="201 attributes="
202 setNew
203 setUnapproved202 setUnapproved
204 setRejected203 setRejected
205 setAccepted204 setAccepted
206205
=== modified file 'lib/lp/soyuz/model/packagecopyjob.py'
--- lib/lp/soyuz/model/packagecopyjob.py 2014-05-15 08:49:44 +0000
+++ lib/lp/soyuz/model/packagecopyjob.py 2014-05-30 12:14:46 +0000
@@ -515,8 +515,7 @@
515 raise CannotCopy("Package %r %r not found." % (name, version))515 raise CannotCopy("Package %r %r not found." % (name, version))
516 return source_package516 return source_package
517517
518 def _checkPolicies(self, source_name, source_component=None,518 def _checkPolicies(self, source_name, source_package, auto_approve=False):
519 auto_approve=False):
520 # This helper will only return if it's safe to carry on with the519 # This helper will only return if it's safe to carry on with the
521 # copy, otherwise it raises SuspendJobException to tell the job520 # copy, otherwise it raises SuspendJobException to tell the job
522 # runner to suspend the job.521 # runner to suspend the job.
@@ -532,7 +531,8 @@
532 # metadata.531 # metadata.
533 defaults = UnknownOverridePolicy().calculateSourceOverrides(532 defaults = UnknownOverridePolicy().calculateSourceOverrides(
534 self.target_archive, self.target_distroseries,533 self.target_archive, self.target_distroseries,
535 self.target_pocket, [source_name], source_component)534 self.target_pocket, [source_name],
535 source_package.sourcepackagerelease.component)
536 self.addSourceOverride(defaults[0])536 self.addSourceOverride(defaults[0])
537 if auto_approve:537 if auto_approve:
538 auto_approve = self.target_archive.canAdministerQueue(538 auto_approve = self.target_archive.canAdministerQueue(
@@ -556,6 +556,29 @@
556 self.requester, self.getSourceOverride().component,556 self.requester, self.getSourceOverride().component,
557 self.target_pocket, self.target_distroseries)557 self.target_pocket, self.target_distroseries)
558558
559 # Go through the same routine for binary overrides if necessary. We
560 # assume that the above permission check on the source component is
561 # sufficient.
562 if self.include_binaries:
563 binaries = source_package.getBuiltBinaries()
564 bpn_archtag = [(
565 bpph.binarypackagerelease.binarypackagename,
566 bpph.distroarchseries.architecturetag) for bpph in binaries]
567 ancestry = override_policy.calculateBinaryOverrides(
568 self.target_archive, self.target_distroseries,
569 self.target_pocket, bpn_archtag)
570 if len(ancestry) != len(binaries):
571 # XXX cjwatson bug=1079577: Binary overrides for Ubuntu
572 # should be calculated using the Ubuntu override policy, and
573 # they should be saved in the metadata with an API for
574 # overriding them.
575 approve_new = auto_approve or copy_policy.autoApproveNew(
576 self.target_archive, self.target_distroseries,
577 self.target_pocket)
578 if not approve_new:
579 self._createPackageUpload()
580 raise SuspendJobException
581
559 # The package is not new (it has ancestry) so check the copy582 # The package is not new (it has ancestry) so check the copy
560 # policy for existing packages.583 # policy for existing packages.
561 approve_existing = auto_approve or copy_policy.autoApprove(584 approve_existing = auto_approve or copy_policy.autoApprove(
@@ -643,9 +666,7 @@
643 [self.context.id]).any()666 [self.context.id]).any()
644 if pu is None:667 if pu is None:
645 source_name = getUtility(ISourcePackageNameSet)[self.package_name]668 source_name = getUtility(ISourcePackageNameSet)[self.package_name]
646 self._checkPolicies(669 self._checkPolicies(source_name, source_package, self.auto_approve)
647 source_name, source_package.sourcepackagerelease.component,
648 self.auto_approve)
649670
650 # The package is free to go right in, so just copy it now.671 # The package is free to go right in, so just copy it now.
651 ancestry = self.target_archive.getPublishedSources(672 ancestry = self.target_archive.getPublishedSources(
652673
=== modified file 'lib/lp/soyuz/tests/test_packagecopyjob.py'
--- lib/lp/soyuz/tests/test_packagecopyjob.py 2014-05-15 09:06:24 +0000
+++ lib/lp/soyuz/tests/test_packagecopyjob.py 2014-05-30 12:14:46 +0000
@@ -18,6 +18,7 @@
18from zope.security.proxy import removeSecurityProxy18from zope.security.proxy import removeSecurityProxy
1919
20from lp.bugs.interfaces.bugtask import BugTaskStatus20from lp.bugs.interfaces.bugtask import BugTaskStatus
21from lp.buildmaster.enums import BuildStatus
21from lp.registry.interfaces.pocket import PackagePublishingPocket22from lp.registry.interfaces.pocket import PackagePublishingPocket
22from lp.registry.interfaces.series import SeriesStatus23from lp.registry.interfaces.series import SeriesStatus
23from lp.registry.model.distroseriesdifferencecomment import (24from lp.registry.model.distroseriesdifferencecomment import (
@@ -1003,6 +1004,40 @@
1003 [removeSecurityProxy(job).context.id]).one()1004 [removeSecurityProxy(job).context.id]).one()
1004 self.assertEqual(PackageUploadStatus.NEW, pu.status)1005 self.assertEqual(PackageUploadStatus.NEW, pu.status)
10051006
1007 def test_copying_new_binaries(self):
1008 # A copy involving source and new binaries requires NEW queue approval.
1009 target_archive = self.factory.makeArchive(
1010 self.distroseries.distribution, purpose=ArchivePurpose.PRIMARY)
1011 source_archive = self.factory.makeArchive()
1012 old_spph = self.publisher.getPubSource(
1013 distroseries=self.distroseries, sourcename="copyme", version="1.0",
1014 status=PackagePublishingStatus.PUBLISHED, archive=target_archive)
1015 self.publisher.getPubBinaries(
1016 binaryname="copyme", pub_source=old_spph,
1017 distroseries=self.distroseries,
1018 status=PackagePublishingStatus.PUBLISHED)
1019 new_spph = self.publisher.getPubSource(
1020 distroseries=self.distroseries, sourcename="copyme", version="1.1",
1021 status=PackagePublishingStatus.PUBLISHED, archive=source_archive)
1022 for build in new_spph.createMissingBuilds():
1023 build.updateStatus(BuildStatus.FULLYBUILT)
1024 for binaryname in ("copyme", "libcopyme-dev"):
1025 bpr = self.publisher.uploadBinaryForBuild(build, binaryname)
1026 self.publisher.publishBinaryInArchive(
1027 bpr, new_spph.archive,
1028 status=PackagePublishingStatus.PUBLISHED)
1029 pu = self.publisher.addPackageUpload(
1030 new_spph.archive, self.distroseries,
1031 changes_file_name="copyme_1.1_%s.changes" % build.arch_tag)
1032 pu.addBuild(build)
1033 job = self.createCopyJobForSPPH(
1034 new_spph, source_archive, target_archive, include_binaries=True)
1035 self.runJob(job)
1036 self.assertEqual(JobStatus.SUSPENDED, job.status)
1037 pu = getUtility(IPackageUploadSet).getByPackageCopyJobIDs(
1038 [removeSecurityProxy(job).context.id]).one()
1039 self.assertEqual(PackageUploadStatus.NEW, pu.status)
1040
1006 def test_copying_to_main_archive_unapproved(self):1041 def test_copying_to_main_archive_unapproved(self):
1007 # Uploading to a series that is in a state that precludes auto1042 # Uploading to a series that is in a state that precludes auto
1008 # approval will cause the job to suspend and a packageupload1043 # approval will cause the job to suspend and a packageupload
@@ -1302,6 +1337,10 @@
1302 distroseries=self.distroseries, sourcename="copyme",1337 distroseries=self.distroseries, sourcename="copyme",
1303 version="2.8-0", status=PackagePublishingStatus.PUBLISHED,1338 version="2.8-0", status=PackagePublishingStatus.PUBLISHED,
1304 component='multiverse', section='web', archive=target_archive)1339 component='multiverse', section='web', archive=target_archive)
1340 self.publisher.getPubBinaries(
1341 binaryname="copyme", pub_source=old_spph,
1342 distroseries=self.distroseries,
1343 status=PackagePublishingStatus.PUBLISHED)
1305 old_spr = old_spph.sourcepackagerelease1344 old_spr = old_spph.sourcepackagerelease
1306 diff_file = self.publisher.addMockFile("diff_file", restricted=True)1345 diff_file = self.publisher.addMockFile("diff_file", restricted=True)
1307 package_diff = old_spr.requestDiffTo(target_archive.owner, spr)1346 package_diff = old_spr.requestDiffTo(target_archive.owner, spr)